存储过程中的SQL Server / Create视图

时间:2014-03-28 10:58:20

标签: sql-server stored-procedures

我正在尝试从存储过程中创建一个视图,并且很难看到来自非常类似方法的两个相反的结果。

示例1

CREATE PROCEDURE cv AS
GO
DECLARE @sql nvarchar(MAX)
SET @sql = 'CREATE VIEW test AS SELECT * FROM someOtherTable'
exec (@sql)

虽然此示例在第一次创建过程后创建视图,但在以后使用以下步骤执行过程时,它不会重新创建视图:

EXEC cv

示例2

CREATE PROCEDURE cv 
@table SYSNAME
AS
DECLARE @sql nvarchar(MAX)
SET @sql = 'CREATE VIEW '+ @table +' AS SELECT * FROM someOtherTable'

这个过程在第一次创建过程时不创建视图,但每次调用后都会创建视图:

EXEC @sql;

为什么会这样?我认为这真的令人困惑,没有意义或是这样吗?

5 个答案:

答案 0 :(得分:3)

第1次陈述

CREATE PROCEDURE cv AS
GO                      --<-- This GO here terminates the batch
DECLARE @sql nvarchar(MAX)
SET @sql = 'CREATE VIEW test AS SELECT * FROM someOtherTable'
exec (@sql)

GO批处理终结器创建过程并立即执行以下语句。因此,您可以创建一个为您创建视图的过程。

事实上,这两个批次是两个陈述。

- BATCH 1

CREATE PROCEDURE cv AS
GO 

- BATCH 2

DECLARE @sql nvarchar(MAX)
SET @sql = 'CREATE VIEW test AS SELECT * FROM someOtherTable'
exec (@sql)

批处理1创建一个内部没有任何内容的过程,但它为您创建一个过程对象,根本没有功能/定义。

单独执行关键字GO后的语句并为您创建视图。

我的建议

在创建对象之前,请务必检查对象是否存在。我会写这样的程序..

CREATE PROCEDURE cv 
AS
BEGIN
 SET NOCOUNT ON;

IF OBJECT_ID ('test', 'V') IS NOT NULL
 BEGIN
   DROP VIEW test
 END

    DECLARE @sql nvarchar(MAX)
    SET @sql = 'CREATE VIEW test AS SELECT * FROM someOtherTable'
    exec (@sql)
END 

答案 1 :(得分:0)

在示例1中 - 您正在创建一个带有硬编码测试名称的视图。在proc的后续运行中,由于视图已经存在,SQL Server将抛出一个错误,因为您正在尝试创建一个与已存在的视图同名的视图。

在示例2中,您将视图的名称作为参数传递。这将始终创建一个新视图,除非您传入的@table值对应于现有视图。

只是想知道 - 为什么要使用存储过程创建视图?这不是您通常在SQL中执行的操作。

答案 2 :(得分:0)

您需要更改

EXEC @sql致EXEC (sql)

EXEC可用于运行存储过程,而不是动态sql

例如

declare @dd varchar(100)='Select ''A'''

exec (@dd) ->will work fine
exec @dd   -> Error

详细了解The Curse and Blessings of Dynamic SQL

答案 3 :(得分:0)

创建视图语句不能与存储过程一起使用

答案 4 :(得分:0)

EXEC ('CREATE VIEW ViewName AS SELECT * FROM OPENQUERY(Yourservername,''EXECUTE [databasename].[dbo].[sp_name] ''''' +Parameter + ''''''')')