动态sql变量问题需要修复

时间:2012-03-11 17:18:15

标签: sql-server-2008 sql-server-2008-r2 dynamic-sql

我在使用动态sql的sql server 2008 r2中向存储过程添加第二个变量时看似微不足道的变化,我收到了一个新错误:

Msg 206, Level 16, State 2, Line 1
Operand type clash: date is incompatible with int

当我运行下面的下一个代码块时(后面的代码块是我的代码)

DECLARE @tableName varchar(120)
SET @tableName = 'tblDailySMA'
DECLARE @mxDate DATE
SET @mxDate = dbo.LatestDateWithPricingVolCountOver4k()
EXEC sprocAddDatesSymbolsAndPeriodsToAggregatedStudy @tableName, @mxDate

USE [Market]
GO
/****** Object:  StoredProcedure [dbo].[sprocAddDatesSymbolsAndPeriodsToAggregatedStudy]    Script Date: 03/11/2012 12:55:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sprocAddDatesSymbolsAndPeriodsToAggregatedStudy]
    @table varchar(120), @maxDate DATE

AS

EXEC(
    ';WITH t1 AS
    (
        SELECT Symbol, TradingDate
        FROM tblSymbolsMain
        CROSS JOIN tblTradingDays
        WHERE TradingDate <=' + @maxDate +
    '), 

    t2 AS
    (
        SELECT Symbol, TradingDate, Period
        FROM t1
        CROSS JOIN tblPeriods
    )

    INSERT INTO ' + @table + ' (Symbol, TradeDate, Period)
    (SELECT Symbol, TradingDate, Period
    FROM t2
    EXCEPT
        (SELECT t3.Symbol, t3.TradeDate, t3.Period
         FROM ' + @table + '))')

RETURN

我确信这是一个非常简单的快速解决方案,我可以忽略什么?提前谢谢。

2 个答案:

答案 0 :(得分:3)

您需要使用单引号括起日期参数。要将它们嵌入到动态SQL中,您需要逃避它们。

'... WHERE TradingDate <= ''' + CONVERT(CHAR(8), @maxDate, 112) + ''' ...'

或者让它更容易阅读(取决于人,我猜):

'... WHERE TradingDate <= ' + CHAR(39) + CONVERT(CHAR(8), @maxDate, 112) + CHAR(39) + ' ...'

也许另一个问题是你不想连接并在EXEC内调用convert和其他内置函数,如何:

ALTER PROCEDURE [dbo].[sprocAddDatesSymbolsAndPeriodsToAggregatedStudy]
    @table   VARCHAR(120), 
    @maxDate DATE
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @sql NVARCHAR(MAX) = N';WITH t1 AS
    (
        SELECT Symbol, TradingDate
        FROM tblSymbolsMain
        CROSS JOIN tblTradingDays
        WHERE TradingDate <= ''' + CONVERT(CHAR(8), @maxDate, 112) +
    '''), 
    t2 AS
    (
        SELECT Symbol, TradingDate, Period
        FROM t1
        CROSS JOIN tblPeriods
    )
    INSERT INTO ' + @table + ' (Symbol, TradeDate, Period)
    (SELECT Symbol, TradingDate, Period
    FROM t2
    EXCEPT
        (SELECT t3.Symbol, t3.TradeDate, t3.Period
         FROM ' + @table + '))';

    EXEC sp_executesql @sql;
END
GO

答案 1 :(得分:1)

您可能希望将@maxDate转换为字符类型数据类型,以便它可以与动态sql的其余部分连接(注意我不是鼓励动态sql)< / p>

即。类似的东西:

';WITH t1 AS
(
    SELECT Symbol, TradingDate
    FROM tblSymbolsMain
    CROSS JOIN tblTradingDays
    WHERE TradingDate <=''' + CONVERT(varchar(20), @maxDate, 120) + '''
'), 

有关CONVERT选项的信息,请参阅http://msdn.microsoft.com/en-us/library/ms187928.aspx