是否可以使用 sp_executesql 创建视图?
Posted
技术标签:
【中文标题】是否可以使用 sp_executesql 创建视图?【英文标题】:Is it possible to use sp_executesql to create a view? 【发布时间】:2019-06-10 14:43:53 【问题描述】:我可以使用以下语句在我的数据库中创建一个空的存储过程:
declare @statement as NVARCHAR(250)
set @statement = N'CREATE PROCEDURE [dbo].[vwAS2ConnectionUpdated] as'
exec dbo.sp_executesql @statement
但是,如果我尝试使用相同的语句创建视图(在创建语句中使用 VIEW 除外)* 我会收到错误。
declare @statement as NVARCHAR(250)
set @statement = N'CREATE VIEW [dbo].[vwAS2ConnectionUpdated] as'
exec dbo.sp_executesql @statement
错误是:
Incorrect syntax near 'as'.
你能告诉我为什么会发生这种情况吗?
注意:我已经浏览过其他类似的 SO Q&A,但没有明确的答案。 这是我读过的一个例子: error in EXECUTE sp_executesql
注意 2:我在 SQL Server Express 实例上运行它 -- SQL Server 2014 SP3 CU3 - 12.0.6259.0(最新版本)
其他信息
当您使用代码创建 SP 时,它最终会创建一个如下所示的 SP:
CREATE PROCEDURE [dbo].[vwAS2ConnectionUpdated] as
但是,它不会创建这样的视图。也许这是 SQL Server 解析器等中的一个错误,或者是 sp_executesql(它允许这样创建 SP??)
【问题讨论】:
你的陈述的其余部分在哪里?VIEW
是预编译的 SELECT
语句;你的VIEW
定义没有SELECT
声明
可以,但为什么要这样做?
@Larnu 这是由 RoundhouseE 实现的更大脚本的一部分,它检查 SP(或在本例中为 View)的存在。这只是那个脚本的一个 sn-p。
@Sami 这是一个较大脚本的一部分,它确定 VIEW 是否存在,如果不存在,则创建它,然后运行 ALTER 之后。这是使用 RoundhouseE 的模式/过程。
没有人可以调试看不见的代码。
【参考方案1】:
可以通过sp_executesql
使用CREATE VIEW
,见下面的例子:
declare @statement as NVARCHAR(250)
set @statement = N'CREATE VIEW [dbo].[MyView] as SELECT 1 [ColumnName]'
exec dbo.sp_executesql @statement
SELECT [ColumnName]
FROM [dbo].[MyView]
您看到错误的原因是您没有指定视图应该执行的SELECT
语句。如果您查看CREATE VIEW
的文档,您会发现select_statement
未在brackets ([]
) 中列出,这意味着它不是可选的。
CREATE PROCEDURE
的文档显示了过程主体的语法:
AS [ BEGIN ] sql_statement [;] [ ...n ] [ END ]
这分解为:
以AS
开头
BEGIN
和 END
是可选的
可以有一个或多个 sql_statement
s 可选地以分号结尾
粗略搜索后,我在任何地方都找不到sql_statement
的语法,但看起来空字符串确实是有效的sql_statement
。 CREATE PROCEDURE [dbo].[AnotherProcedure] as ;
将创建存储过程这一事实支持这一点。
【讨论】:
这是迄今为止最好的答案,但我想相关的问题是,“为什么你可以创建这样的 SP,但不能创建这样的视图?这是我问题的根源。跨度> 我将把这个标记为答案,因为您提到了 Create View 文档和将 AS 语句显示为非可选的括号。我将它与 Create PROCEDURE 进行了比较,它显示该部分是可选的。这很奇怪,但至少现在我有一个明确的答案。 @raddevus,我添加了更多细节,从CREATE PROCEDURE
文档中挑选出一些语法 =)
注意:如果VIEW
已经存在会报错。【参考方案2】:
是否可以使用 sp_executesql 创建视图?
是的,可以创建类似的视图
EXEC sp_exeutesql N'DROP VIEW IF EXISTS [dbo].[MyView]; CREATE VIEW [MyView] AS SELECT 1 AS Col';
现在,让我们看看为什么不直接N'CREATE VIEW [dbo].[vwAS2ConnectionUpdated] as'
访问CREATE VIEW
页面,可以看到定义:
创建一个虚拟表,其内容(列和行)...
虽然N'CREATE VIEW [dbo].[vwAS2ConnectionUpdated] as'
似乎没有列和行,但是当您定义一个表时,该表应该有列。
另外,如果你看一下你会发现的语法
AS select_statement
所以,它是CREATE VIEW
语法的一部分,这意味着您需要一个SELECT
语句。
另外,如果你看看 Arguments 部分,你会看到
select_statement
是定义视图的 SELECT 语句。该语句可以使用多个表和其他视图。需要适当的权限才能从创建的视图的 SELECT 子句中引用的对象中进行选择。
因此,如果您不包含SELECT
语句,则根本没有定义您的视图,它是VIEW
的定义,因此应该使用它。
【讨论】:
非常好的信息,非常感谢,但其他帖子是第一位的,所以我会标记为答案。感谢您提供有价值的详细信息。 @raddevus 没关系,挑一个最好的就行了,读者可以从帖子中学习,知道哪个是最好的;)以上是关于是否可以使用 sp_executesql 创建视图?的主要内容,如果未能解决你的问题,请参考以下文章
SQLServer : EXEC和sp_executesql的区别