在 SQL Server 2012 的存储过程中执行多条语句和 CTE?

Execute multiple statements and CTE in stored procedure in SQL Server 2012?

我是 SQL 服务器 2012 的新手,我正在尝试创建一个存储过程,它应该:

  1. 根据参数从table中删除以前的数据,然后
  2. 在 table 上插入新数据。

但我需要使用 CTEs 出于性能和其他原因( 不要挂断电话,我有到,请相信我的话)。

如果 CTE 查询本身位于存储过程中,则它可以正常工作,但我无法让 SP 使用两个子句。

我在尝试创建过程时遇到错误,抱怨我应该在 CTE 之前使用分号。如果我添加分号,SQL 服务器也会抱怨。这让我发疯,请帮助

Table 我想 delete/insert:

CREATE MYTABLE ( APPUSER NVARCHAR(15), DATA NVARCHAR(100) )

简化存储过程(无分号):

CREATE PROCEDURE P1 ( @SOMEUSER NVARCHAR(15), @TYPE INTEGER) AS
BEGIN
    DELETE FROM MYTABLE WHERE ( APPUSER=@SOMEUSER )

    WITH CTE AS (
        SELECT DATA
        FROM SOURCETABLE
        WHERE ( TYPE = @TYPE )
    )
    INSERT INTO MYTABLE
    SELECT
        @SOMEUSER,
        DATA
    FROM CTE 
END

没有分号的错误信息:

[Error Code: 319, SQL State: S1000] Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.

请注意,即使这是实际查询的简化版本,错误也完全相同。我确实尝试了上面的代码,但没有任何运气:(

带分号的存储过程(与上面相同的查询,为简洁起见仅显示分号):

(...)
BEGIN
    DELETE FROM MYTABLE WHERE ( APPUSER=@SOMEUSER ); /* Semicolon */

    WITH CTE AS (    
(...)

分号错误:

[Error Code: 102, SQL State: 42000] Incorrect syntax near ')'.

我尝试将 DELETE 子句包含在它自己的事务中,这也不起作用,总是出现两个错误之一。

任何指点将不胜感激,谢谢!!!

你需要放一个';'在 'With' 关键字之前,您的代码如下所示

CREATE PROCEDURE P1 ( @SOMEUSER NVARCHAR(15), @TYPE INTEGER) AS
BEGIN
    DELETE FROM MYTABLE WHERE ( APPUSER=@SOMEUSER )

    ;WITH CTE AS (
        SELECT DATA
        FROM SOURCETABLE
        WHERE ( TYPE = @TYPE )
    )
    INSERT INTO MYTABLE
    SELECT
        @SOMEUSER,
        DATA
    FROM CTE 
END

作为 CTE 的经验法则,如果您的 CTE 之上有任何可执行语句,请始终以分号开头。

你发生了一些奇怪的事情,因为以下对我有用:

CREATE PROCEDURE P1 ( @SOMEUSER NVARCHAR(15), @TYPE INTEGER) AS
BEGIN
    DELETE FROM [Table_1] WHERE ( [lname]=@SOMEUSER );

    WITH CTE AS (
        SELECT [fname], [lname]
        FROM [Table_1]
        WHERE ( [ID] = @TYPE )
    )
    INSERT INTO [Table_1]
    SELECT top 1
        @SOMEUSER,
        [lname],
        @TYPE
    FROM CTE 
END

检查您的环境

CTE 只是语法 - 它对性能没有帮助

为了完全清楚其他人提出的观点,此摘录形式 the MSDN documentation on CTE's in SQL Server 是使用 CTE 的基本注意事项:

•When a CTE is used in a statement that is part of a batch, the statement before it must be followed by a semicolon.

如前所述,最佳做法是:

  • 养成所有SQL语句以分号结束的习惯;或
  • 学习并记住所有必需的分号,例如此处,并在所有这些结构前加一个分号。

我更喜欢第一种,但我见过有能力的开发人员更喜欢第二种。