我正在尝试使用@table
和OPENROWSET
循环插入@param
参数。我改编自This Answer的代码,该代码演示了如何使用Dynamic SQL插入参数。
代码:
DECLARE @BuildTimes TABLE (
BuildTableName VARCHAR(max) NULL
,BuildDate DATE NULL
)
DECLARE @days INT = 0;
DECLARE @startDate DATE = GETDATE();
DECLARE @buildDate DATE = GETDATE();
DECLARE @sql nvarchar(max);
WHILE (@days <=30)
BEGIN
SET @buildDate = DATEADD(day, -1*@days, @startDate);
SET @sql='INSERT INTO @BuildTimes
SELECT *
FROM OPENROWSET(
''SQLNCLI'',
''SERVER=localhost;Trusted_Connection=yes;'',
''EXEC [LOG].[BuildTimes] @buildDate = ''''' + CAST(@buildDate AS VARCHAR) +''''''')'
PRINT @sql
EXEC(@sql)
SET @days = @days + 1
END
SELECT * FROM @BuildTimes
错误:
Msg 1087, Level 15, State 2, Line 9
Must declare the table variable "@BuildTimes"
我尝试将OPENROWSET作为不带参数的非动态SQL运行,并且一切正常。我在做什么错了?
答案 0 :(得分:2)
在动态SQL中无法访问您的变量表@BuildTimes
。即使您声明了它并用动态SQL加载了它,您也将无法读取超出动态范围的结果。
一种解决方案是使用临时表而不是变量表:
IF OBJECT_ID('tempdb..#BuildTimes') IS NOT NULL
DROP TABLE #BuildTimes
CREATE TABLE #BuildTimes (
BuildTableName VARCHAR(max) NULL
,BuildDate DATE NULL
)
DECLARE @days INT = 0;
DECLARE @startDate DATE = GETDATE();
DECLARE @buildDate DATE = GETDATE();
DECLARE @sql nvarchar(max);
WHILE (@days <=30)
BEGIN
SET @buildDate = DATEADD(day, -1*@days, @startDate);
SET @sql='INSERT INTO #BuildTimes
SELECT *
FROM OPENROWSET(
''SQLNCLI'',
''SERVER=localhost;Trusted_Connection=yes;'',
''EXEC [LOG].[BuildTimes] @buildDate = ''''' + CAST(@buildDate AS VARCHAR) +''''''')'
PRINT @sql
EXEC(@sql)
SET @days = @days + 1
END
SELECT * FROM #BuildTimes
该表可以在EXEC
外部读取,因为它是在外部创建的,并且可以在内部访问,因为它保留在同一会话中。
作为旁注,请避免在希望使用一组已知列的情况下使用*
,这样,如果在SELECT
的基础表上添加了新列,则INSERT
不会破裂。
答案 1 :(得分:1)
为什么要完全使用动态SQL,而不仅仅是使用18.01-0.7
?
8-0.7
答案 2 :(得分:0)
我发现在这种情况下我根本不需要Dynamic SQL / OPENROWSET。以下代码可产生所需的结果:
DECLARE @BuildTimes TABLE (
BaseTableName VARCHAR(max) NULL
,BuildDate DATE NULL
,StartDateTime DATETIME NULL
,FinishDateTime DATETIME NULL
,TimeTakenMinutes BIGINT NULL
)
DECLARE @days INT = 0;
DECLARE @startDate DATE = GETDATE();
DECLARE @thisBuildDate DATE = GETDATE();
WHILE (@days <=30)
BEGIN
SET @thisBuildDate = DATEADD(day, -1*@days, @startDate);
PRINT @thisBuildDate
INSERT INTO @BuildTimes
EXEC [LOG].[BuildTimes] @buildDate = @thisBuildDate
SET @days = @days + 1
END
SELECT * FROM @BuildTimes
GO