SQL:无法在块内创建SP

VSO*_*VSO 2 t-sql sql-server scripting stored-procedures

如果表尚不存在,我试图运行一些SQL查询,具体来说:

  1. 创建表.
  2. 添加一些数据.
  3. 创建存储过程以访问数据.

第1步和第2步工作正常,但是当我尝试执行第三部分时,我收到错误.这是我的代码(不需要仔细阅读 - 这里作为参考,跳到下面的问题区域):

USE [MyDB]
GO


IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='fooTable' and xtype='U')
    BEGIN
        CREATE TABLE fooTable
        (
            ID INT NOT NULL IDENTITY(1,1),
            SomeNumber INT NOT NULL, 
            SomeOtherTable_ID INT NOT NULL, 
            PRIMARY KEY (ID),
            FOREIGN KEY (SomeOtherTable_ID) REFERENCES SomeOtherTable(SomeOtherTable_ID)
        );

        INSERT INTO fooTable (SomeNumber, SomeOtherTable_ID)
        VALUES (5, 1), (10, 1), (25, 1), (50, 1), (100, 1), (500, 1)

        CREATE PROCEDURE myProcedureName
        AS
        SELECT SomeNumber from [fooTable]
    END 
Run Code Online (Sandbox Code Playgroud)

相关的故障线是这里的第三个,它在if语句的外部工作正常:

CREATE PROCEDURE myProcedureName
AS
SELECT SomeNumber from [fooTable]
Run Code Online (Sandbox Code Playgroud)

但如果我尝试在if块中运行它,请SELECT使用以下内容以红色加下划线:

SELECT附近的语法不正确.期待外在.

如何在if块中运行存储过程?如果它是相关的,这是在使用T-SQL的SQL Server中.

Sol*_*zky 5

存储过程,触发器,函数和其他几种对象类型需要在它们自己的批处理中.这可以IF通过将CREATE语句包装在一个块中来实现EXEC(N'....'):

IF (OBJECT_ID(N'dbo.footTable') IS NULL)
BEGIN
   CREATE TABLE dbo.[fooTable]
   (
      ID INT NOT NULL IDENTITY(1, 1)
           CONSTRAINT [PK_fooTable] PRIMARY KEY,
      SomeNumber INT NOT NULL, 
      SomeOtherTable_ID INT NOT NULL
           CONSTRAINT [FK_fooTable_SomeOtherTable] FOREIGN KEY
           REFERENCES dbo.SomeOtherTable(SomeOtherTable_ID)
   );

   INSERT INTO dbo.fooTable (SomeNumber, SomeOtherTable_ID)
   VALUES (5, 1), (10, 1), (25, 1), (50, 1), (100, 1), (500, 1);

   EXEC(N'
        CREATE PROCEDURE dbo.myProcedureName
        AS
        SELECT SomeNumber FROM [fooTable];
   ');
END;
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 确保N在包含动态SQL的字符串文字中包含大写前缀(作为最佳实践 - 是的,没有它经常有效,但让它始终有效).

  • 请勿使用已弃用的兼容性视图,例如sysobjects.从SQL Server 2005的发布开始,sys架构中包含正确的系统目录视图.在这种情况下,它会sys.objects.

  • 您应该对对象进行架构限定:dbo.fooTable而不仅仅是fooTable

  • 您应该命名您的约束:PK,FK等.