【问题标题】:SQL Parameterised column namesSQL 参数化列名
【发布时间】:2016-04-20 11:02:26
【问题描述】:

我正在尝试创建参数化查询以从表中检索数据

基本上我有一个表结构 ID nvarchar1 文本 日期时间1 日期时间2

我正在尝试执行这样的查询,以便它选择当前日期大于 datetime1 且小于 datetime2 的所有数据

SELECT 
    ID, nvarchar1, 
    ntext, 
    datetime1, 
    datetime2 
FROM 
    TABLEName 
WHERE 
    datetime1 >= @CurrentDate 
    AND datetime2 <= @CurrentDate

我想制作列参数,例如 @TableName、@CurrentDate、@StartDate、@EndDate

DECLARE @TableName NVARCHAR(100);
SET @TableName = '[Surveys].[dbo].[Table]'

DECLARE @CurrentDate DateTime;
SET @CurrentDate = GETDATE();

DECLARE @StartDate NVARCHAR(100);
SET @StartDate = 'datetime1'

DECLARE @EndDate NVARCHAR(100);
SET @EndDate = 'datetime2'

DECLARE @sql nvarchar(1000)
SET @sql = 'SELECT * FROM ' + @TableName + 'WHERE' + @EndDate + '>=' + @CurrentDate + 'AND' +  @StartDatedatetime1 + '<=' + @CurrentDate
EXEC(@sql)

数据将来自 SP 数据源,因此我无法控制列名等,当我创建 SP 列表时,它们会自动分配给该类型的表列,所以这就是我需要列作为参数。

使用上面我认为应该可以工作的代码返回

消息 241,第 16 级,状态 1,第 14 行 从字符串转换日期和/或时间时转换失败。

我做错了什么?

【问题讨论】:

  • 那么你的问题是什么?
  • datetime 类型的变量不需要引号。 ICBW。

标签: sql-server tsql variables dynamic-sql


【解决方案1】:

试试下面的。正如@GordonLinoff 所说,您在@CurrentDate 变量周围缺少单引号(')。此外,您将DATETIME 参数传递给@sql 变量,该变量是NVARCHAR 数据类型。这些不是隐式转换的,所以@CurrentDate变量需要先转换为NVARCHAR

DECLARE @sql nvarchar(1000)
SET @sql = 'SELECT * FROM ' + @TableName 
    + ' WHERE ' + @EndDate + ' >= ''' + CONVERT(NVARCHAR(50), @CurrentDate,120) 
    + ''' AND ' +  @StartDate + ' <= ''' + CONVERT(NVARCHAR(50), @CurrentDate,120) + ''''


EXEC(@sql)

【讨论】:

  • 如果你看 Gordons 的回答,你会看到,参数是在没有转换的情况下传入的,并且在查询的文本中没有引号......参数的使用是为了避免 在查询中字面上给出的值。其次:特别是在处理日期时间值时,应尽可能避免转换(如果不可避免,更喜欢126)。
  • 结果是一列未命名,其值为 ---- SELECT * FROM [Surveys].[dbo].[z_TEST] WHERE datetime2 >= '2016-04-20 13:24 :25' AND datetime1
  • 应将 CurrentDate 变量设置为 DateTime,StartDate 和 EndDate 应为 DateTime 还是应为 nvarchar 并在 select 语句中转换?
  • @Shnugo 感谢您的评论。我正在处理 klydemonroe 收到的错误。戈登的回答是我将如何处理这种情况。但它没有解决错误的原因,任何在类似情况下收到相同错误的人都找不到解决问题的参考。
  • @KlydeMonroe @StartDate@EndDate 变量不应该引用 @TableName 变量中保存的表的列名吗?
【解决方案2】:

你很接近。我会为表构造 SQL,然后使用当前日期的参数:这将是这样的:

SET @sql = '
SELECT *
FROM @TableName
WHERE datetime2 >= @CurrentDate AND datetime1 <= @CurrentDate';

SET @sql = REPLACE(@sql, '@TableName', @TableName);

exec sp_executesql @sql, N'@CurrentDate date', @CurrentDate = @CurrentDate;

顺便说一句,您的查询的问题是日期常量周围缺少单引号。

编辑:

您不能使用参数替换列名或表名。我会把代码写成:

SET @sql = '
SELECT *
FROM @TableName
WHERE @datetime2 >= @CurrentDate AND @datetime1 <= @CurrentDate';

SET @sql = REPLACE(@sql, '@TableName', @TableName);
SET @sql = REPLACE(@sql, '@datetime1', @DateTime1);
SET @sql = REPLACE(@sql, '@datetime2', '@DateTime2);

。 . .

我将REPLACE() 用于此类操作,因为代码更易于理解和维护。

【讨论】:

  • 我不确定我是否理解......我的工作方式如下...... DECLARE @ CurrentDate DateTime; SET@CurrentDate = GETDATE(); SELECT TOP 1000 [ID] ,[nvarchar1] ,[ntext2] ,[datetime1] ,[datetime2] FROM [Surveys].[dbo].[z_TEST] WHERE datetime2 >= @ CurrentDate AND datetime1
猜你喜欢
  • 2013-03-03
  • 2010-09-11
  • 2010-09-27
  • 2018-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-08
  • 2021-02-18
相关资源
最近更新 更多