问题
I am using VS 2012 and SQL Express
I am trying to build a windows forms application to search through a database in C# and it has different controls on the form which are passed as parameters to the query.
The parameters in the query are not necessarily passed some times
I am trying with the following code sample.
SELECT a.ID AS 'DealID', a.TradeDate, c.COMPANYNAME AS 'Seller Company',
a.SellCommission, h.BROKER_FULLNAME AS 'Seller Trader',
j.DisplayName AS 'Seller Broker', d.COMPANYNAME AS 'Buyer Company',
a.BuyCommission, g.BROKER_FULLNAME AS 'Buyer Trader',
i.DisplayName AS 'Buyer Broker', e.PRODUCT_NAME, f.TYPE_DESC AS 'Quantity Type',
f.NBR_OF_GALLONS AS 'Quantity Multiplier', a.ContractVolume, a.TotalVolume,
a.DeliveryPoint, a.Price, a.ContractStart, a.ContractEnd
FROM Confirmations AS a WITH (nolock)
LEFT OUTER JOIN COMPANY AS c WITH (nolock)
ON c.COMPANY_ID = a.SellCompany
LEFT OUTER JOIN COMPANY AS d WITH (nolock)
ON d.COMPANY_ID = a.BuyCompany
LEFT OUTER JOIN BIOPRODUCTTYPES AS e WITH (nolock)
ON e.ID = a.ProductID
LEFT OUTER JOIN BIO_QUANTITY_TYPE AS f WITH (nolock)
ON f.ID = a.QuantityTypeID
LEFT OUTER JOIN COMPANYBROKER AS g WITH (nolock)
ON g.COMPANYBROKER_ID = a.BuyTrader
LEFT OUTER JOIN COMPANYBROKER AS h WITH (nolock)
ON h.COMPANYBROKER_ID = a.SellTrader
LEFT OUTER JOIN Users AS i WITH (nolock)
ON i.ID = a.BuyBroker
LEFT OUTER JOIN Users AS j WITH (nolock)
ON j.ID = a.SellBroker
WHERE (@fromdate IS NULL OR @fromdate=' ' OR a.TradeDate >= @fromdate)
AND (@todate IS NULL OR @todate=' ' OR a.TradeDate <= @todate)
AND (@buycompanyname IS NULL
OR @buycompanyname=""
OR a.BuyCompany = (SELECT COMPANY_ID
FROM COMPANY
WHERE (COMPANYNAME = @buycompanyname)))
AND (@sellcompanyname IS NULL
OR @sellcompanyname=""
OR a.SellCompany = (SELECT COMPANY_ID
FROM COMPANY
WHERE (COMPANYNAME =@sellcompanyname)))
AND (@product IS NULL OR @product="" OR e.PRODUCT_NAME= @product)";
Rather than using the above query, can I dynamically create a query, based on the parameters I passed which seems more logical as it doesn't look for the records if the column in the table has a null value.
回答1:
If you are calling a stored procedure, I'd suggest dynamically building the SQL string to only use the parameters you'll be using, then calling sp_executesql. The stored procedure would look like this:
DECLARE @sql =nvarchar(MAX), @Parameters nvarchar(max)
SET @sql = 'SELECT * FROM [dbo].[Foo] WHERE Column1 = @Param1'
SET @Parameters = '@Param1 nvarchar(32), @Param2 nvarchar(32)'
IF(@Param2 is not null and @Param2 <> ' ') SET @sql = @sql + ' AND Column2 = @Param2'
EXEC sp_executesql @Sql, @Parameters, @Param1, @Param2
The idea is basically the same if you're building the query string in C# instead of a stored procedure:
command.CommandText = "SELECT * FROM [dbo].[Foo] WHERE Column1 = @Param1";
command.Parameters.AddWithValue("@Param1", param1);
if(!String.IsNullOrEmpty(param2))
{
command.CommandText += " AND Column2 = @Param2";
command.Parameters.AddWithValue("@Param2", param2);
}
回答2:
This is what ORM's where created for. By replacing your hard coded querys with somthing that builds your query at runtime (like Entity Framework or NHibernate) and it builds the both the SELECT
and the WHERE
portions of the query for you.
With proper set up objects you could use Entity Framework like the following
Nullable<DateTime> fromDate = //...
Nullable<DateTime> toDate = //...
string buyCompany = //...
//(Snip)
using(var ctx = new MyContext())
{
var query = ctx.Order;
if(fromDate.HasValue)
query = query.Where(ent=> ent.TradeDate >= fromDate.Value);
if(toDate.HasValue)
query = query.Where(ent => ent.TradeDate <= toDate.Value);
if(String.IsNullOrWhitespace(buyCompany) == false)
query = query.Where(ent => ent.BuyCompany.CompanyName = buyCompany);
//(Snip)
return query.ToList();
}
回答3:
Yes, just build your sql query string out.
Set your SqlCommand.CommandType
to CommandType.Text
then set your parameters with SqlCommand.Parameters.AddWidthValue(string, object);
来源:https://stackoverflow.com/questions/17977917/how-can-we-create-a-dynamic-sql-query-to-run-without-considering-if-the-paramete