问题描述
我已经使用sql Server创建了下表
CREATE TABLE test
(
id_number NVARCHAR(50) NOT NULL,number_of_products NVARCHAR(50) NOT NULL
);
INSERT INTO test (id_number,number_of_products)
VALUES (1000077004,3),(1000077005,4),(1000077006,(1000077007,5),(1000077008,(1000077009,6);
我还使用动态sql创建了一个自定义过程,以运行面向自定义的查询
程序:
CREATE PROCEDURE [dbo].[usp_dynamicquery1]
(@TableName NVARCHAR(50) = NULL,@Field NVARCHAR(100) = NULL,@Criterion NVARCHAR(100) = NULL,@Parameter NVARCHAR(100) = NULL)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql NVARCHAR(MAX)
DECLARE @ParameterDef NVARCHAR(500)
DECLARE @all VARCHAR(2) = '-1'
SET @ParameterDef = '@TableName NVARCHAR(50),@Field NVARCHAR(100),@Criterion NVARCHAR(100),@Parameter NVARCHAR(100)'
SET @sql = 'SELECT *
FROM TableName
WHERE Field Criterion Parameter'
SET @TableName = CASE
WHEN @TableName IS NOT NULL AND @TableName <> 0
THEN SET @sql = @sql+ ' AND TableName = @TableName'
ELSE '''' + @all + ''' = ''' + @all + ''''
END
SET @Field = CASE
WHEN @Field IS NOT NULL AND @Field <> 0
THEN SET @sql = @sql+ ' AND Field = @Field'
ELSE '''' + @all + ''' = ''' + @all + ''''
END
SET @Criterion = CASE
WHEN @Criterion = 'greater than'
THEN SET @sql = @sql+ ' AND Criterion = >'
WHEN @Criterion = 'greater than or equal'
THEN SET @sql = @sql+ ' AND Criterion = >='
WHEN @Criterion = 'less than'
THEN SET @sql = @sql+ ' AND Criterion = <'
WHEN @Criterion = 'less than or equal'
THEN SET @sql = @sql+ ' AND Criterion = <='
WHEN @Criterion = 'equal'
THEN SET @sql = @sql+ ' AND Criterion = ='
WHEN @Criterion = 'not equal'
THEN SET @sql = @sql+ ' AND Criterion = <>'
ELSE '''' + @all + ''' = ''' + @all + ''''
END
SET @Parameter = CASE
WHEN @Parameter IS NOT NULL AND @Parameter <> 0
THEN SET @sql = @sql+ ' AND Parameter = @Parameter'
ELSE '''' + @all + ''' = ''' + @all + ''''
END
EXEC sp_executesql @sql,@ParameterDef,@TableName = @TableName,@Field = @Field,@Criterion = @Criterion,@Parameter = @Parameter
END
简而言之,我将解释我的程序的作用:
-
步骤1:将4个参数(
TableName,Field,Criterion,Parameter
)作为输入 -
步骤2:设置查询以根据样本条件(大于,小于等)选择所有值
-
步骤3:运行4条if-else语句来定义每个变量的值。基本上,如果用户提供一个值,则参数采用该值,否则参数采用值“ -1”(@ all)
当我尝试创建过程时,出现以下错误:
消息156,级别15,状态1,过程usp_dynamicquery1,行45 [批处理开始行0]
关键字“ SET”附近的语法不正确。信息156,级别15,状态1,过程usp_dynamicquery1,第46行[批处理开始第0行]
关键字“ ELSE”附近的语法不正确。信息156,级别15,状态1,过程usp_dynamicquery1,第51行[批处理开始第0行]
关键字“ SET”附近的语法不正确。
我在下面运行查询时的预期结果:
[usp_dynamicquery1] @TableName='test',@Field='number_of_products',@Criterion='greater than',@Parameter = '4'
返回number_of_products> 4(因此测试表的最后三行)的id编号。
解决方法
您有正确的想法,并朝着正确的方向前进。我想我会帮你的忙,以帮助您学习如何解决这个问题。
这是我的存储过程版本:
CREATE OR ALTER PROCEDURE [dbo].[usp_dynamicquery1] (
@TableName NVARCHAR(50),@Field NVARCHAR(100) = NULL,@Criterion NVARCHAR(100) = NULL,@Parameter NVARCHAR(100) = NULL,@All VARCHAR(2) = '-1'
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE
@SQL NVARCHAR(MAX),@SQL_WHERE NVARCHAR(MAX),@ParameterDef NVARCHAR(500);
SET @ParameterDef = '@Parameter NVARCHAR(100)'
SET @SQL = 'SELECT * FROM ' + @TableName;
SET @SQL_WHERE = '';
/* BUILD THE WHERE CLAUSE IF @Field IS PRESENT */
IF NULLIF ( @Field,'' ) IS NOT NULL BEGIN
-- Field.
SET @SQL_WHERE = ' WHERE ' + @Field;
-- Field Comparison.
SET @SQL_WHERE += CASE @Criterion
WHEN 'greater than' THEN ' >'
WHEN 'greater than or equal' THEN ' >='
WHEN 'less than' THEN ' <'
WHEN 'less than or equal' THEN ' <='
WHEN 'not equal' THEN ' <>'
ELSE ' ='
END;
-- Field Parameter.
SET @SQL_WHERE += ' @Parameter';
-- Set @Parameter value.
SET @Parameter =
CASE WHEN NULLIF ( @Parameter,'' ) IS NOT NULL
THEN @Parameter
ELSE @All
END;
END
-- Finish SQL statement.
SET @SQL = @SQL + ISNULL ( @SQL_WHERE,'' ) + ';';
-- Execute the dynamic statement.
EXEC sp_executesql @SQL,@ParameterDef,@Parameter = @Parameter;
END
GO
一些值得注意的快速提示
-
@TableName
必须,否则,您打算查询什么? -
仅在存在
WHERE
的情况下构造@Field
子句。 -
将
@ParameterDef
变量缩短为仅包含@Parameter
。其余的t-sql是在调用sp_execute_sql
之前形成的。我离开了@Parameter,这样您就不必担心值等周围的单个滴答声。 -
如果需要,可以将
@All
作为DEFAULT
ed参数(-1)添加到SP的值可以更改。