【问题标题】:SQL Server Cursor Dynamic SQL Incorrect syntax near 'SOURCE.dbo.SRC_KLIENT'SQL Server 游标动态 SQL 'SOURCE.dbo.SRC_KLIENT' 附近的语法不正确
【发布时间】:2019-04-13 18:09:19
【问题描述】:
declare kursor cursor for 
    select 
        exec_No, insert_type, stg_table, src 
    from 
        METADATA.dbo.METADATA 
    order by 
        exec_No asc;

    declare @insert_type varchar(15), @stg_table varchar(30), 
            @src varchar(80), @SQL varchar(254), @exec_No numeric(2), 
            @SQL_INSERT varchar(254);

    open kursor

    fetch next from kursor into @exec_No, @insert_type, @stg_table, @src;

    while @@FETCH_STATUS = 0
    begin
        if @insert_type = 'select' 
        begin
            --  select @SQL = 'IF OBJECT_ID('''+@stg_table+''') IS NOT NULL DROP TABLE '+@stg_table;
            select @SQL = 'DROP TABLE IF EXISTS '+@stg_table;
            select @SQL_INSERT = 'select * from '''+@src+''' as '+@stg_table;
            exec(@SQL);
            execute(@SQL_INSERT);

            fetch next from kursor into @exec_No, @insert_type, @stg_table, @src;
        end 

        if @insert_type = 'bulk'
        begin
            execute ('truncate table ' + @stg_table);
            execute('BULK INSERT '+@stg_table+' 
                     FROM ''' + @src + ''' 
                     WITH
                         (
                            FIELDTERMINATOR = '',''
                         )')
        end

        fetch next from kursor into @exec_No, @insert_type, @stg_table, @src;
    end

    close kursor;
    deallocate kursor;

我得到错误

消息 102,第 15 级,状态 1,第 1 行
'SOURCE.dbo.SRC_KLIENT' 附近的语法不正确。

消息 102,第 15 级,状态 1,第 1 行
'SOURCE.dbo.SRC_MIEJSCOWOSC' 附近的语法不正确。

消息 102,第 15 级,状态 1,第 1 行
'SOURCE.dbo.SRC_PRACOWNIK' 附近的语法不正确。

消息 102,第 15 级,状态 1,第 1 行
'SOURCE.dbo.SRC_MELDUNEK' 附近的语法不正确。

错误是由语句产生的:

select @SQL_INSERT = 'select * from '''+@src+''' as '+@stg_table;

我的元数据插入:

insert into 
METADATA.dbo.METADATA(exec_No,src,stg_table,temp_table, chd_table, insert_type) 
values(1,'SOURCE.dbo.SRC_KLIENT', 'STAGE.dbo.STG_KLIENT', 'TEMP.dbo.TEMP_KLIENT', 'CHD.dbo.KLIENT', 'select');

insert into 
METADATA.dbo.METADATA(exec_No,src,stg_table,temp_table, chd_table, insert_type) 
values(15,'SOURCE.dbo.SRC_MELDUNEK', 'STAGE.dbo.STG_MELDUNEK', 'TEMP.dbo.TEMP_MELDUNEK', 'CHD.dbo.MELDUNEK', 'select');

任何想法如何让它工作?

谢谢大家!

【问题讨论】:

  • PRINT(或SELECT)动态 SQL 语句变量的值。如果您无法找出问题所在,请粘贴这些 PRINT 语句的输出。 'select * from '''+@src+''' as '+@stg_table; 是不对的(对象名称没有用单引号引起来 ('))。 QUOTENAME 是你的朋友,但你的数据有问题(解释如下)。
  • 啊,您在表中存储了一个完整的对象名称。这是个问题;不。将部分拆分为数据中的数据库、模式和对象名称;然后您可以单独引用每个部分。否则你会让自己容易被注射;这是一个问题。
  • 另外,在旁注中。格式化代码是一件非常有用的事情。您在该查询中没有缩进,因此很难理解。您有多个IFWHILE 语句,无法分辨END 属于哪个BEGIN。在编写 SQL 时养成使用缩进和换行的习惯。左不规则的代码是写 SQL 的好方法。
  • 它不会运行,但这里有一个db<>fiddle,其中包含一些格式化代码和一些 cmets。
  • 谢谢。是否有可能使我的代码工作?它适用于小型项目 - 我没有太多时间来更改 METADATA 表结构。我会记住,最好将数据拆分为更小的部分。您能尝试更正我的代码吗?

标签: sql sql-server sql-server-2017 database-cursor


【解决方案1】:

我终于做到了。 有一个工作(我现在知道它不安全)代码:

declare 
    kursor cursor for select exec_No, insert_type, stg_table, src from METADATA.dbo.METADATA order by exec_No ASC;
    declare @insert_type varchar(15), @stg_table varchar(30), @src varchar(80), @SQL varchar(254), @exec_No numeric(2), @SQL_INSERT varchar(254);
    open kursor
    fetch next from kursor
    into @exec_No, @insert_type, @stg_table, @src;

    WHILE @@FETCH_STATUS = 0
        begin
            if @insert_type = 'select' 
            begin
                select @SQL = 'DROP TABLE IF EXISTS '+@stg_table;
                select @SQL_INSERT = 'select * into ' + @stg_table + ' from ' + @src;
                print(@SQL);
                print(@SQL_INSERT);
                exec(@SQL);
                exec(@SQL_INSERT);
            end 
            if @insert_type = 'bulks'
            begin
            execute ('truncate table ' + @stg_table);
            execute('BULK INSERT '+@stg_table+' 
                        FROM ''' + @src + ''' 
                        WITH
                        (
                        FIELDTERMINATOR = '',''
                        )')
            end
            fetch next from kursor
            into @exec_No, @insert_type, @stg_table, @src;
        end

    CLOSE kursor;
    deallocate kursor;

在 SQL Server 中 select * from table_1 as table_2 不是正确的查询。正确的是select * into table_2 from table_1

还有重复的“fetch next ...”块(一个在第一个 if,另一个在 ifs 外面)。

感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2017-07-15
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多