我之前已经运行过几次这种类型的代码,但是在另一个组织中的另一个环境中,而不是在SQL Server上完全相同的版本中。下面的示例代码已简化,但可以作为我的问题的示例。
在此示例中,我尝试进行几年的循环(“ ar”变量),并在另一个数据库中(而不是保存原始表的位置)每年创建一个新表。原始表包括所有年份。原始表中的“ ar”变量是一个整数。
我的代码如下:
declare @Ar int = 2007
declare @ArVC varchar(4)=''
declare @CreateTable varchar(MAX)=''
declare @DB varchar(MAX)='MIRK3utv'
while @Ar <= 2015
begin
set @ArVC = cast(@Ar as varchar)
set @CreateTable = '
select *
into ' + @DB + 'dbo.Tab_' + @ArVC + '
from DBorg.dbo.OrgTab
where ar = ' + @ArVC
exec @CreateTable
set @Ar = @Ar + 1
end
这给了我一个错误:
Msg 203,第16级,状态2,第34行 名字 ' 选择 * 进入MIRK3utv.dbo.Tab_2007 来自DBorg.dbo.OrgTab 其中ar = 2007'不是有效的标识符。
我在这里想念什么?我已经在网上和这个论坛上搜索了答案,但在这种情况下似乎找不到适合我的解决方案。
答案 0 :(得分:3)
要执行动态SQL,您有两个选择:使用EXEC(@SQL)
或使用EXEC sp_ExecuteSql @Sql
。
请注意,第一个选项包括括号-如果没有括号,SQL Server会假定您正在尝试执行存储过程-这就是为什么您会出错的原因。
您在问题中发布的代码也缺少将数据库名称与模式名称分隔开的点,但是它确实出现在错误消息中,因此我认为这只是问题本身的错字。
您可以像这样运行这段代码:
declare @Ar int = 2007
declare @ArVC varchar(4)=''
declare @CreateTable varchar(MAX)=''
declare @DB varchar(MAX)='MIRK3utv'
while @Ar <= 2015
begin
set @ArVC = cast(@Ar as varchar)
set @CreateTable = '
select *
into ' + @DB + '.dbo.Tab_' + @ArVC + ' -- added the missing dot
from DBorg.dbo.OrgTab
where ar = ' + @ArVC
exec(@CreateTable) -- Note the parenthesis!
set @Ar = @Ar + 1
答案 1 :(得分:0)
我会这样写:
declare @Ar int = 2007;
declare @CreateTable nvarchar(MAX) = N''
declare @DB nvarchar(MAX)= N'MIRK3utv'
while @Ar <= 2015
begin
set @CreateTable = N'
select *
into ' + @DB + '.dbo.Tab_@Ar
from DBorg.dbo.OrgTab
where ar = @Ar';
set @CreateTable = replace(@CreateTable, @Ar);
exec sp_executesql @CreateTable
set @Ar = @Ar + 1
end;
答案 2 :(得分:0)
怎么样
DECLARE @SQL NVARCHAR(MAX) = '';
WITH Years AS
(
SELECT 2007 Ar
UNION ALL
SELECT Ar + 1
FROM Years
WHERE Ar < 2015
)
SELECT @SQL = @SQL +
N'SELECT * INTO MIRK3utv.dbo.Tab_' +
CAST(Ar AS VARCHAR) +
' FROM DBorg.dbo.OrgTab WHERE Ar = ''' +
CAST(Ar AS VARCHAR) + '''; '
FROM Years;
SELECT @SQL;
--EXECUTE sp_executesql @SQL;
我不明白为什么你需要在这里使用循环