我有一个存储过程,它应该从根据提供的参数过滤的表中返回结果集。
更新
alter procedure Proc_CheckExchange
@Flag varchar(3),
@symbol varchar(13)=null,
@exchange char(3)=null,
@limit money=null,
@chargerate numeric(18,4)=null,
@ChgType char(2)=null,
@IsActive int=null,
@Mkrid varchar(11)=null,
@statecode varchar(4) =null
as
declare @sql nvarchar(max)
set @sql = N'select * from Tbl_StampDutyException1 where 1 = 1'
if(@Flag='CHK')
begin
if len(isnull(@exchange, '')) > 0
set @sql = @sql + N'and exchange=@exchange'+ cast(@exchange as nvarchar(100))
if len(isnull(@symbol, '')) > 0
set @sql = @sql + N'and symbol=@symbol'+ cast(@symbol as nvarchar(100))
if len(isnull(@limit, '')) > 0
set @sql = @sql + N'and limit=@limit'+ cast(@limit as nvarchar(100))
if len(isnull(@chargerate, '')) > 0
set @sql = @sql + N'and chargerate=@chargerate'+ cast(@chargerate as nvarchar(100))
if len(isnull(@ChgType, '')) > 0
set @sql = @sql + N'and ChgType=@ChgType'+ cast(@ChgType as nvarchar(100))
if len(isnull(@IsActive, '')) > 0
set @sql = @sql + N'and IsActive=@IsActive'+ cast(@IsActive as nvarchar(100))
if len(isnull(@statecode, '')) > 0
set @sql = @sql + N'and statecode=@statecode'+ cast(@statecode as nvarchar(100))
exec (@sql)
end
if (@Flag='ALL')
begin
select * from Tbl_StampDutyException1
end
更新1
alter procedure Proc_CheckExchange
@Flag varchar(3),
@symbol varchar(13)=null,
@exchange char(3)=null,
@limit money=null,
@chargerate numeric(18,4)=null,
@ChgType char(2)=null,
@IsActive int=null,
@Mkrid varchar(11)=null,
@statecode int =null
as
declare @sql nvarchar(max)
set @sql = N'select * from Tbl_StampDutyException1 where 1 = 1'
if(@Flag='CHK')
begin
if len(isnull(@exchange, '')) > 0
set @sql = @sql + N' and exchange = @exchange'
if len(isnull(@limit, '')) > 0
set @sql = @sql + N' and limit = @limit'
if len(isnull(@chargerate, '')) > 0
set @sql = @sql + N' and chargerate = @chargerate'
if len(isnull(@ChgType, '')) > 0
set @sql = @sql + N' and ChgType = @ChgType'
if len(isnull(@IsActive, '')) > 0
set @sql = @sql + N' and IsActive = @IsActive'
if len(isnull(@statecode, '')) > 0
set @sql = @sql + N' and statecode = @statecode'
if len(isnull(@symbol, '')) > 0
set @sql = @sql + N' and symbol = @symbol'
declare @params as nvarchar(max) = N'@Flag varchar(3),
@symbol varchar(13),
@exchange char(3),
@limit money,
@chargerate numeric(18,4),
@ChgType char(2),
@IsActive int,
@Mkrid varchar(11),
@statecode varchar(4)'
print @sql
--EXECUTE sp_executesql @sql, @params, @Flag, @symbol, @exchange, @limit, @chargerate, @ChgType, @IsActive, @Mkrid, @statecode
end
我正在尝试创建一个存储过程,其中WHERE
子句中的条件将与传递给存储过程的条件一样多。我希望我清楚自己要实现的目标。我收到错误Error converting data type varchar to numeric.
答案 0 :(得分:1)
您可以做的是使用动态SQL重写存储过程,并且只有在定义了参数时才包含部分where
子句,例如:用
declare @sql nvarchar(max)
set @sql = N'select * from Tbl_StampDutyException1 where 1 = 1'
if len(isnull(@exchange, '')) > 0
set @sql = @sql + N' and exchange = ' + cast(@exchange as nvarchar(100))
-- add all parameters; you need to cast them to nvarchar if they have other type
exec (@sql)
作为改进,您可以使用sp_executesql
来执行动态SQL。有关如何使用它,请参阅here。在这种情况下,代码将是:
declare @sql nvarchar(max)
set @sql = N'select * from Tbl_StampDutyException1 where 1 = 1'
if len(isnull(@exchange, '')) > 0
set @sql = @sql + N' and exchange = @exchange'
-- add all parameters;
declare @params as nvarchar(max) = N'@Flag varchar(3),
@symbol varchar(13),
@exchange char(3),
@limit money,
@chargerate numeric(18,4),
@ChgType char(2),
@IsActive int,
@Mkrid varchar(11),
@statecode varchar(4)'
EXECUTE sp_executesql @sql, @params, @Flag, @symbol, @exchange, @limit, @chargerate, @ChgType, @IsActive, @Mkrid, @statecode
顺便说一句,不要在存储过程中使用select *
,这不是一个好习惯。列出要返回的所有列。否则,如果表定义发生更改,您将获得与之前相同的结果。
答案 1 :(得分:0)
我猜您需要的是一个条件WHERE CLAUSE方法,提供了下面的示例脚本,您需要将所有IF条件转换为CASE然后您可以将所有条件组合到一个SELECT语句中:
SELECT * FROM Tbl_StampDutyException1
WHERE
exchange = CASE WHEN @exchange='' or @exchange is null THEN exchange ELSE @exchange END
AND symbol = Case when @symbol='' or @symbol is null THEN symbol ELSE symbol
AND *so on.....*
答案 2 :(得分:0)
我认为这是一个很好的解决方案
SELECT * from dbo.Clients
WHERE
(@param1 IS NULL OR field1 = @param1)
AND (@param2 IS NULL OR field2 = @param2)
使用这种方法,每次执行查询时,服务器都不会重新处理语句(执行计划)。