【问题标题】:How can I get the definition of a view with the correct name?如何获得具有正确名称的视图的定义?
【发布时间】:2020-11-18 05:08:12
【问题描述】:

我有一个数据库,其中包含过去由用户手动重命名的多个视图。

如果我尝试获取视图的定义以便我可以在其他地方编写它的创建脚本,the name comes out wrong。我可以使用以下方法在幕后获取具有“错误”名称的数据库列表:

SELECT OBJECT_NAME(object_id), definition
FROM sys.sql_modules
WHERE convert(nvarchar(200),definition) not like ('%'+OBJECT_NAME(object_id)+'%')

有没有办法获得视图的正确定义,因为它将生成具有新名称的视图?或者,有没有办法提取视图的幕后名称,以便我可以在使用它之前在定义中使用正确的名称 replace 它?


真正烦人的是,如果我使用 GUI 来“将视图编写为 > CREATE 到 > 新建查询编辑器窗口”,它会生成正确的 CREATE 脚本,因此 SSMS 显然可以通过某种方式访问​​这些信息:

【问题讨论】:

  • 尝试删除视图并重新创建它们。我认为这是重命名的错误。

标签: sql sql-server tsql


【解决方案1】:

有什么方法可以得到正确的视图定义,因为它会生成具有新名称的视图?

是的。使用 SMO(在代码或 PowerShell 中)或 SSMS(使用 SMO)为视图编写脚本。 SMO 是所有 SQL Server 对象的全保真脚本引擎。

使用 Powershell,您可以轻松地自动执行此操作,例如:

$sql = Get-SqlInstance -ServerInstance "localhost"
$db = $sql | get-sqldatabase -Name "AdventureWorks2017"
foreach ($v in $db.Views)
{
   [Microsoft.SqlServer.Management.Smo.View] $vv = $v
   write-host $vv.Script()
}

从 Profiler 来看,这里没有服务器端功能在起作用。 SMO 获取视图定义,并具有 TSQL 解析器,因此它可以在编写对象脚本时修复 DDL。这是 SMO 运行以获取视图主体的查询:

SELECT
CAST(
        serverproperty(N''Servername'')
       AS sysname) AS [Server_Name],
db_name() AS [Database_Name],
SCHEMA_NAME(v.schema_id) AS [Schema],
v.name AS [Name],
CAST(ISNULL(OBJECTPROPERTYEX(v.object_id,N''ExecIsQuotedIdentOn''),0) AS bit) AS [QuotedIdentifierStatus],
CAST(
 case 
    when v.is_ms_shipped = 1 then 1
    when (
        select 
            major_id 
        from 
            sys.extended_properties 
        where 
            major_id = v.object_id and 
            minor_id = 0 and 
            class = 1 and 
            name = N''microsoft_database_tools_support'') 
        is not null then 1
    else 0
end          
             AS bit) AS [IsSystemObject],
CAST(ISNULL(OBJECTPROPERTYEX(v.object_id,N''ExecIsAnsiNullsOn''),0) AS bit) AS [AnsiNullsStatus],
v.object_id AS [ID],
NULL AS [Text],
ISNULL(smv.definition, ssmv.definition) AS [Definition]
FROM
sys.all_views AS v
LEFT OUTER JOIN sys.sql_modules AS smv ON smv.object_id = v.object_id
LEFT OUTER JOIN sys.system_sql_modules AS ssmv ON ssmv.object_id = v.object_id
WHERE
(v.type = @_msparam_0)and(v.name=@_msparam_1 and SCHEMA_NAME(v.schema_id)=@_msparam_2)
ORDER BY
[Database_Name] ASC,[Schema] ASC,[Name] ASC',N'@_msparam_0 nvarchar(4000),@_msparam_1 nvarchar(4000),@_msparam_2 nvarchar(4000)

【讨论】:

  • 您能否详细说明如何在程序上完成此操作?这里隐含的目标是我想自动化它,而不是使用 GUI 手动执行步骤。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多