Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有标量变量的SQL while循环_Sql_Sql Server_Sql Server 2014_Declare_Scalar - Fatal编程技术网

带有标量变量的SQL while循环

带有标量变量的SQL while循环,sql,sql-server,sql-server-2014,declare,scalar,Sql,Sql Server,Sql Server 2014,Declare,Scalar,我以前曾多次运行过此类代码,但都是在另一个组织的另一个环境中运行的,而SQL Server上的版本并不完全相同。下面的示例代码是简化的,但它是我的问题的一个示例 在本例中,我尝试在几年内循环ar变量,并在另一个数据库中创建一个新表,而不是在保存原始表的位置。原始表格包括所有年份。原始表中的ar变量是int 我的代码如下所示: declare @Ar int = 2007 declare @ArVC varchar(4)='' declare @CreateTable varchar(MAX)='

我以前曾多次运行过此类代码,但都是在另一个组织的另一个环境中运行的,而SQL Server上的版本并不完全相同。下面的示例代码是简化的,但它是我的问题的一个示例

在本例中,我尝试在几年内循环ar变量,并在另一个数据库中创建一个新表,而不是在保存原始表的位置。原始表格包括所有年份。原始表中的ar变量是int

我的代码如下所示:

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
这给了我一个错误,它说:

味精203,16级,状态2,第34行 名字是 挑选* 进入MIRK3utv.dbo.Tab_2007 从DBorg.dbo.OrgTab 其中ar=2007'不是有效的标识符

我错过了什么?我在网上和这个论坛上搜索了答案,但在这种情况下,我似乎找不到适合我的解决方案。

我将这样写:

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;

要执行动态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
怎么样

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;
我不明白你为什么要在这里使用循环


你应该使用QUOTENAME@DB和QUOTENAME'Tab'+@ArVC以避免SQL注入。和@CreateTable应为NVARCHARMAX以支持Unicode命名的对象,@DB也应为Unicode,最好为sysname类型,因为它确实代表一个系统对象一个DB名称,将@ArVC作为参数传递给sp_executesql,以避免在exec SQL中嵌入值的问题:set@CreateTable=N'select*from。。。其中ar=@ArVC和exec sp_executesql@createSQL,N'@ArVC varchar4',@ArVC是迄今为止唯一一个解释OP代码产生错误原因的回复。非常感谢!是的,当我输入问题时,点是我的错误。我的代码在一个看起来有点像的环境中,所以我不能复制它。括号起了作用。它们在我的其他代码中,所以我一定是在那里失去了我的大脑,令人惊讶的是,在我数小时的错误检查中,我从未注意到它再次感谢。很高兴能帮助您:-