【问题标题】:SQL Server view - bad naming convention?SQL Server 视图 - 错误的命名约定?
【发布时间】:2018-05-23 22:50:16
【问题描述】:
DECLARE @TableName AS VARCHAR(250);
DECLARE @SQL AS VARCHAR(500);
DECLARE @ViewCheck as CURSOR;

SET @ViewCheck = CURSOR FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'VIEW' AND TABLE_NAME LIKE 'V_WFC%'

OPEN @ViewCheck

FETCH NEXT FROM @ViewCheck INTO @TableName

WHILE @@FETCH_STATUS = 0
BEGIN

Set @SQL = 'SELECT TOP 10 * FROM ' + @TableName 

PRINT(@SQL)
EXEC(@SQL)

FETCH NEXT FROM @ViewCheck INTO @TableName;
END

CLOSE @ViewCheck

我有一个游标,它遍历特定​​架构中的所有 SQL 视图,以健全性检查它们是否继续运行,有些与报告相关联,有些用作 ProSolution 中的应用程序数据源。

其中一个视图被命名为 UnmarkedRegister(Today),括号用于将其与类似视图区分开来,该视图在应用程序中用于驱动显示数据。

当查询按预期运行时,返回正确的数据——游标返回错误

消息 208,第 16 级,状态 1,第 1 行
无效的对象名称“V_WFC_UnmarkedRegister”

我想知道为什么在游标的 EXEC(SQL) 部分中省略了括号部分?

【问题讨论】:

  • 除非你有一些非常奇怪的对象名称,否则这真的不太可能烧毁你,但如果你实际上正在寻找名称以“V_WFC”开头的视图,那么请改用LIKE 'V[_]WFC%'。方括号指示LIKE 将下划线解释为文字字符;否则它是一个匹配任何单个字符的通配符。例如,一个名为 VXWFC_UnmarkedRegister 的视图将满足您原来的 LIKE 表达式。

标签: sql sql-server


【解决方案1】:

使用quotename():

Set @SQL = 'SELECT TOP 10 * FROM ' + QUOTENAME(@TableName);

【讨论】:

  • 成功了,谢谢。 SELECT TOP 10 * FROM [V_WFC_UnmarkedRegister(Today)](0 行受影响)
  • 它可能值得explaining what this does,以及为什么它在没有引号的情况下会失败:括号构成 t-sql 中用于 UDF 调用的语法的一部分。不使用方括号,t-sql 的分词器将其分隔为标识符V_WFC_UnmarkedRegister 和参数Today。在评估这个不存在的参数之前,它会查找不在模式中的标识符。接下来它会抱怨函数调用不需要模式前缀,但那是另一回事了。
【解决方案2】:

我真的很讨厌游标,这里根本不需要游标。您可以通过多种方式大大简化此代码。首先,我使用 sys.views 而不是 INFORMATION_SCHEMA 视图。然后我使用 sql 来构建动态 sql 字符串而不是游标。看看这有多简单。

declare @SQL nvarchar(max) = '';

select @SQL = @SQL + 'select top 10 * from ' + QUOTENAME(v.name) + '; select ''('' + convert(varchar(2), @@ROWCOUNT) + '' rows affected'';'
from sys.views v
where v.name LIKE 'V_WFC%'

print @SQL
exec sp_executesql @SQL

【讨论】:

  • 如果您在dbo 架构之外有任何视图,则需要在from 子句中添加到sys.schemas s on v.schema_id = s.schema_id 的连接,并在select 子句中添加QUOTENAME(s.name) + '.' +
  • @tarheel 同意。但由于 OP 只查看默认模式,我认为不需要扩展它。
  • 由于“拥有”数据库的应用程序的限制,所有视图都存储在单独的报告数据库中,并且不会超出该架构,但这是公平的。
  • 我不介意光标,我喜欢你的产品,但在这种情况下光标的好处是输出的格式。 SELECT TOP 10 * FROM [V_WFC_ApplicationOffering](受影响的 10 行)
  • 光标是魔鬼的产物。当不需要时,它们经常被用作拐杖。你可以很容易地通过行数来完成你想要的。请参阅我的编辑。游标的真正问题是它们太慢了。对于像视图这样的小集合来说,这可能没什么大不了的。我只是强烈地鄙视他们,并想方设法根除他们。他们有自己的位置,但少之又少。 :)
【解决方案3】:

因为括号通常标识一个函数调用

改变这一行:

Set @SQL = 'SELECT TOP 10 * FROM ' + @TableName

这应该解决它:

Set @SQL = 'SELECT TOP 10 * FROM [' + @TableName + ']'

【讨论】:

  • 这工作正常,直到您的视图名称中包含]。 :) 当然,在对象名称中使用特殊字符绝不是一个好主意,但是 OP 已经有了一个带有括号的视图,所以,我不建议 假设 他们没有' t 有一个带有] 的视图,它的名称也是安全的。 :)
  • 这将涵盖大多数/所有特殊字符,除了 [ 或 ],不要认为它会让您在表名中使用这些字符。我只是尝试用其中一个创建一个表,但它不允许我使用它。
  • 使用 QUOTENAME 将解决所有情况。 :)
  • @Brad 你可以,你必须将] 加倍,就像在文字字符串中使用' 一样。例如:CREATE TABLE [[IHaveBrackets!!!]]] (ID int);。如果您随后查询sys.tables:SELECT [name] FROM sys.tables WHERE [name] LIKE '%IHaveB%';,您将看到该表是使用名称'[IHaveBrackets!!!]' 创建的。 :)
  • @Larnu 很酷,很高兴知道,我不会做或不应该做任何事情,但很高兴知道以防万一我遇到它谢谢!
猜你喜欢
  • 2017-10-22
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 2011-10-06
  • 2011-08-10
  • 1970-01-01
相关资源
最近更新 更多