.net Sql错误必须声明标量变量,即使在声明变量之后也是如此
下面是我的查询,获取错误.net Sql错误必须声明标量变量,即使在声明变量之后也是如此,.net,sql,sql-server-2008,tsql,.net,Sql,Sql Server 2008,Tsql,下面是我的查询,获取错误必须声明标量变量“@collectionId”,即使我使用[GetAllProductById]6,0,0,0,'A122' ALTER proc [dbo].[GetAllProductById] ( @collectionId int, @GrandId int , @ParentId int , @ChildId int, @dealerid varchar(50) ) As Begin Declare @sql as
必须声明标量变量“@collectionId”
,即使我使用[GetAllProductById]6,0,0,0,'A122'
ALTER proc [dbo].[GetAllProductById]
(
@collectionId int,
@GrandId int ,
@ParentId int ,
@ChildId int,
@dealerid varchar(50)
)
As
Begin
Declare @sql as varchar(max)
-- In case dealer is logged in ,then calculate the Discounted amount and return the same,
-- else return Mrp and Our Price for all other customers
IF @collectionid<=0
BEGIN
IF @dealerid<>''
BEGIN
SET @sql = ' Select Top(5) Product.Id,ProdImage,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((Product.BasicPrice + ValueAdd),0),
Discounted = ISNULL((Select (Product.BasicPrice + (ValueAdd -(ValueAdd *(Discount*0.01))))
From DealerDiscount
Where CategoryId = Product.GrandCategoryId AND DealerId='+@dealerid+'),0)
From Product Where 1=1 ';
END
ELSE
BEGIN
SET @sql = ' Select Top(5) Id,ProdImage,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((BasicPrice + ValueAdd),0), Discounted=0
From Product
Where 1=1 ';
END
END
ELSE
BEGIN
IF @dealerid<>''
BEGIN
SET @sql = ' Select Product.Id,ProdImage,ProductCode,Collections.Name,Collections.Id, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((Product.BasicPrice + ValueAdd),0),
Discounted = ISNULL((Select (Product.BasicPrice + (ValueAdd -(ValueAdd *(Discount*0.01))))
From DealerDiscount
Where CategoryId = Product.GrandCategoryId AND DealerId='+@dealerid+'),0)
FROM Collections INNER JOIN
Product ON Collections.Id = Product.CollectionId
where Product.CollectionId=@collectionId AND 1=1 ';
END
ELSE
BEGIN
SET @sql = ' Select Product.Id,ProdImage,Collections.Name,Collections.Id,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((BasicPrice + ValueAdd),0), Discounted=0
FROM Collections INNER JOIN
Product ON Collections.Id = Product.CollectionId
where Product.CollectionId=@collectionId AND 1=1 ';
END
if (@GrandId > 0 and @ParentId>0 and @ChildId > 0 and @collectionId=0)
Begin
Set @sql = @sql + ' Product.ParentCategoryId = '+ Convert(Varchar, @ParentId)+' AND Product.GrandCategoryId = '+ Convert(Varchar, @GrandId)+' AND Product.ChitdCategoryId = '+Convert(varchar,@ChildId);
End
if (@GrandId > 0 and @ParentId>0 and @ChildId = 0 and @collectionId=0)
Begin
Set @sql = @sql + ' Product.ParentCategoryId = '+ Convert(Varchar, @ParentId)+' AND Product.GrandCategoryId = '+ Convert(Varchar, @GrandId)
End
if (@GrandId > 0 and @ParentId=0 and @ChildId = 0 and @collectionId=0)
Begin
Set @sql = @sql + ' AND Product.GrandCategoryId = '+ Convert(Varchar, @GrandId)
End
END
exec(@sql)
END
ALTER proc[dbo].[GetAllProductById]
(
@集合ID int,
@格兰迪德国际酒店,
@ParentId int,
@儿童智力,
@dealerid varchar(50)
)
作为
开始
将@sql声明为varchar(max)
--如果经销商登录,则计算折扣金额并返回相同金额,
--否则返回Mrp和我们对所有其他客户的价格
如果@collectionid为0且@ParentId>0且@ChildId>0且@collectionid=0)
开始
设置@sql=@sql+'Product.ParentCategoryId='+Convert(Varchar,@ParentId)+'和Product.GrandCategoryId='+Convert(Varchar,@GrandId)+'和Product.ChitdCategoryId='+Convert(Varchar,@ChildId);
终点
if(@GrandId>0和@ParentId>0和@ChildId=0和@collectionId=0)
开始
设置@sql=@sql+'Product.ParentCategoryId='+Convert(Varchar,@ParentId)+'和Product.GrandCategoryId='+Convert(Varchar,@GrandId)
终点
if(@GrandId>0且@ParentId=0且@ChildId=0且@collectionId=0)
开始
设置@sql=@sql+'和Product.GrandCategoryId='+Convert(Varchar,@GrandId)
终点
结束
exec(@sql)
结束
在构建查询时,需要将变量作为字符串追加,而不仅仅是赋值。
请尝试:
ALTER proc [dbo].[GetAllProductById]
(
@collectionId int,
@GrandId int ,
@ParentId int ,
@ChildId int,
@dealerid varchar(50)
)
As
Begin
Declare @sql as varchar(max)
-- In case dealer is logged in ,then calculate the Discounted amount and return the same,
-- else return Mrp and Our Price for all other customers
IF @collectionid<=0
BEGIN
IF @dealerid<>''
BEGIN
SET @sql = ' Select Top(5) Product.Id,ProdImage,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((Product.BasicPrice + ValueAdd),0),
Discounted = ISNULL((Select (Product.BasicPrice + (ValueAdd -(ValueAdd *(Discount*0.01))))
From DealerDiscount
Where CategoryId = Product.GrandCategoryId AND DealerId='+@dealerid+'),0)
From Product Where 1=1 ';
END
ELSE
BEGIN
SET @sql = ' Select Top(5) Id,ProdImage,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((BasicPrice + ValueAdd),0), Discounted=0
From Product
Where 1=1 ';
END
END
ELSE
BEGIN
IF @dealerid<>''
BEGIN
SET @sql = ' Select Product.Id,ProdImage,ProductCode,Collections.Name,Collections.Id, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((Product.BasicPrice + ValueAdd),0),
Discounted = ISNULL((Select (Product.BasicPrice + (ValueAdd -(ValueAdd *(Discount*0.01))))
From DealerDiscount
Where CategoryId = Product.GrandCategoryId AND DealerId='+@dealerid+'),0)
FROM Collections INNER JOIN
Product ON Collections.Id = Product.CollectionId
where Product.CollectionId='+CAST(NVARCHAR(50), @collectionId)+' AND 1=1 ';
END
ELSE
BEGIN
SET @sql = ' Select Product.Id,ProdImage,Collections.Name,Collections.Id,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((BasicPrice + ValueAdd),0), Discounted=0
FROM Collections INNER JOIN
Product ON Collections.Id = Product.CollectionId
where Product.CollectionId='+CAST(NVARCHAR(50), @collectionId)+' AND 1=1 ';
END
if (@GrandId > 0 and @ParentId>0 and @ChildId > 0 and @collectionId=0)
Begin
Set @sql = @sql + ' Product.ParentCategoryId = '+ Convert(Varchar, @ParentId)+' AND Product.GrandCategoryId = '+ Convert(Varchar, @GrandId)+' AND Product.ChitdCategoryId = '+Convert(varchar,@ChildId);
End
if (@GrandId > 0 and @ParentId>0 and @ChildId = 0 and @collectionId=0)
Begin
Set @sql = @sql + ' Product.ParentCategoryId = '+ Convert(Varchar, @ParentId)+' AND Product.GrandCategoryId = '+ Convert(Varchar, @GrandId)
End
if (@GrandId > 0 and @ParentId=0 and @ChildId = 0 and @collectionId=0)
Begin
Set @sql = @sql + ' AND Product.GrandCategoryId = '+ Convert(Varchar, @GrandId)
End
END
exec(@sql)
END
ALTER proc[dbo].[GetAllProductById]
(
@集合ID int,
@格兰迪德国际酒店,
@ParentId int,
@儿童智力,
@dealerid varchar(50)
)
作为
开始
将@sql声明为varchar(max)
--如果经销商登录,则计算折扣金额并返回相同金额,
--否则返回Mrp和我们对所有其他客户的价格
如果@collectionid为0且@ParentId>0且@ChildId>0且@collectionid=0)
开始
设置@sql=@sql+'Product.ParentCategoryId='+Convert(Varchar,@ParentId)+'和Product.GrandCategoryId='+Convert(Varchar,@GrandId)+'和Product.ChitdCategoryId='+Convert(Varchar,@ChildId);
终点
if(@GrandId>0和@ParentId>0和@ChildId=0和@collectionId=0)
开始
设置@sql=@sql+'Product.ParentCategoryId='+Convert(Varchar,@ParentId)+'和Product.GrandCategoryId='+Convert(Varchar,@GrandId)
终点
if(@GrandId>0且@ParentId=0且@ChildId=0且@collectionId=0)
开始
设置@sql=@sql+'和Product.GrandCategoryId='+Convert(Varchar,@GrandId)
终点
结束
exec(@sql)
结束
在构建查询时,需要将变量作为字符串追加,而不仅仅是赋值。
请尝试:
ALTER proc [dbo].[GetAllProductById]
(
@collectionId int,
@GrandId int ,
@ParentId int ,
@ChildId int,
@dealerid varchar(50)
)
As
Begin
Declare @sql as varchar(max)
-- In case dealer is logged in ,then calculate the Discounted amount and return the same,
-- else return Mrp and Our Price for all other customers
IF @collectionid<=0
BEGIN
IF @dealerid<>''
BEGIN
SET @sql = ' Select Top(5) Product.Id,ProdImage,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((Product.BasicPrice + ValueAdd),0),
Discounted = ISNULL((Select (Product.BasicPrice + (ValueAdd -(ValueAdd *(Discount*0.01))))
From DealerDiscount
Where CategoryId = Product.GrandCategoryId AND DealerId='+@dealerid+'),0)
From Product Where 1=1 ';
END
ELSE
BEGIN
SET @sql = ' Select Top(5) Id,ProdImage,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((BasicPrice + ValueAdd),0), Discounted=0
From Product
Where 1=1 ';
END
END
ELSE
BEGIN
IF @dealerid<>''
BEGIN
SET @sql = ' Select Product.Id,ProdImage,ProductCode,Collections.Name,Collections.Id, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((Product.BasicPrice + ValueAdd),0),
Discounted = ISNULL((Select (Product.BasicPrice + (ValueAdd -(ValueAdd *(Discount*0.01))))
From DealerDiscount
Where CategoryId = Product.GrandCategoryId AND DealerId='+@dealerid+'),0)
FROM Collections INNER JOIN
Product ON Collections.Id = Product.CollectionId
where Product.CollectionId='+CAST(NVARCHAR(50), @collectionId)+' AND 1=1 ';
END
ELSE
BEGIN
SET @sql = ' Select Product.Id,ProdImage,Collections.Name,Collections.Id,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((BasicPrice + ValueAdd),0), Discounted=0
FROM Collections INNER JOIN
Product ON Collections.Id = Product.CollectionId
where Product.CollectionId='+CAST(NVARCHAR(50), @collectionId)+' AND 1=1 ';
END
if (@GrandId > 0 and @ParentId>0 and @ChildId > 0 and @collectionId=0)
Begin
Set @sql = @sql + ' Product.ParentCategoryId = '+ Convert(Varchar, @ParentId)+' AND Product.GrandCategoryId = '+ Convert(Varchar, @GrandId)+' AND Product.ChitdCategoryId = '+Convert(varchar,@ChildId);
End
if (@GrandId > 0 and @ParentId>0 and @ChildId = 0 and @collectionId=0)
Begin
Set @sql = @sql + ' Product.ParentCategoryId = '+ Convert(Varchar, @ParentId)+' AND Product.GrandCategoryId = '+ Convert(Varchar, @GrandId)
End
if (@GrandId > 0 and @ParentId=0 and @ChildId = 0 and @collectionId=0)
Begin
Set @sql = @sql + ' AND Product.GrandCategoryId = '+ Convert(Varchar, @GrandId)
End
END
exec(@sql)
END
ALTER proc[dbo].[GetAllProductById]
(
@集合ID int,
@格兰迪德国际酒店,
@ParentId int,
@儿童智力,
@dealerid varchar(50)
)
作为
开始
将@sql声明为varchar(max)
--如果经销商登录,则计算折扣金额并返回相同金额,
--否则返回Mrp和我们对所有其他客户的价格
如果@collectionid为0且@ParentId>0且@ChildId>0且@collectionid=0)
开始
设置@sql=@sql+'Product.ParentCategoryId='+Convert(Varchar,@ParentId)+'和Product.GrandCategoryId='+Convert(Varchar,@GrandId)+'和Product.ChitdCategoryId='+Convert(Varchar,@ChildId);
终点
if(@GrandId>0和@ParentId>0和@ChildId=0和@collectionId=0)
开始
设置@sql=@sql+'Product.ParentCategoryId='+Convert(Varchar,@ParentId)+'和Product.GrandCategoryId='+Convert(Varchar,@GrandId)
终点
if(@GrandId>0且@ParentId=0且@ChildId=0且@collectionId=0)
开始
设置@sql=@sql+'和Product.GrandCategoryId='+Convert(Varchar,@GrandId)
终点
结束
exec(@sql)
结束
您应该修改当前代码以使用生成的TSQL中的sp_executesql
和参数,而不是将值连接到TSQL中,这样可以避免在生成的TSQL中注入SQL的风险,并允许重复使用查询计划。例如:
SET @sql = ' Select Top(5) Product.Id,ProdImage,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((Product.BasicPrice + ValueAdd),0),
Discounted = ISNULL((Select (Product.BasicPrice + (ValueAdd -(ValueAdd *(Discount*0.01))))
From DealerDiscount
Where CategoryId = Product.GrandCategoryId AND DealerId=@dealerid),0)
From Product Where 1=1 ';
....
if (@GrandId > 0 and @ParentId>0 and @ChildId = 0 and @collectionId=0)
Begin
Set @sql = @sql + ' AND Product.ParentCategoryId = @ParentId AND Product.GrandCategoryId = @GrandId '
End
特别要注意的是,我没有将当前参数值连接到生成的SQL中
然后称之为:
exec sp_executesql @sql, N'@dealerid int, @GrandId int',
@dealerid, @GrandId
-- ^^^ todo: add every parameter you need
第一个参数是TSQL;第二个参数(
N'@dealerid int,@GrandId int'
)是一个通过标准SQL语法描述参数的通用参数,然后我们映射要使用的值。在这种情况下,为了方便起见,我们使用了相同的名称-但这不是一个要求。您应该修改当前代码,以便在生成的TSQL中使用sp_executesql
和参数,这避免了在生成的TSQL中注入SQL的风险,并允许重复使用查询计划。例如:
SET @sql = ' Select Top(5) Product.Id,ProdImage,ProductCode, ProductName,MrpPrice, BasicPrice,ValueAdd, Price =ISNULL((Product.BasicPrice + ValueAdd),0),
Discounted = ISNULL((Select (Product.BasicPrice + (ValueAdd -(ValueAdd *(Discount*0.01))))
From DealerDiscount
Where CategoryId = Product.GrandCategoryId AND DealerId=@dealerid),0)
From Product Where 1=1 ';
....
if (@GrandId > 0 and @ParentId>0 and @ChildId = 0 and @collectionId=0)
Begin
Set @sql = @sql + ' AND Product.ParentCategoryId = @ParentId AND Product.GrandCategoryId = @GrandId '
End
特别要注意的是,我没有将当前参数值连接到生成的SQL中
然后称之为:
exec sp_executesql @sql, N'@dealerid int, @GrandId int',
@dealerid, @GrandId
-- ^^^ todo: add every parameter you need
第一个参数是TSQL;第二个参数(
N'@dealerid int,@GrandId int'
)是一个通过标准SQL语法描述参数的通用参数,然后我们映射要使用的值。在这种情况下,为了方便起见,我们使用了相同的名称-但这不是一个要求。IMO,连接输入从来不是一个好方法,并且可能(至少对于[n][var]char
)导致SQL注入错误sp_executesql
将是一种更值得推荐的方法。感谢@marcGravel提供的宝贵提示。堆栈溢出是学习新事物的好地方!依我看,连接输入从来都不是一个好方法,而且可以(至少对于[n]