问题
I have a database with several views that have been manually renamed by users in the past.
If I try to get the definition of the view so that I can script its creation elsewhere, the name comes out wrong. I can get a list of databases with "wrong" names behind-the-scenes using:
SELECT OBJECT_NAME(object_id), definition
FROM sys.sql_modules
WHERE convert(nvarchar(200),definition) not like ('%'+OBJECT_NAME(object_id)+'%')
Is there any way to get the correct definition of the view, in that it will generate the view with the new name? Alternatively, is there a way to extract the behind-the-scenes name of the view so that I can replace
it with the correct name in the definition before using it?
What's really annoying is that if I use the GUI to "Script View as > CREATE to > New Query Editor Window" it results in the correct CREATE script, so SSMS obviously has some way of getting access to this information:
回答1:
Is there any way to get the correct definition of the view, in that it will generate the view with the new name?
Yes. Use SMO (in code or PowerShell) or SSMS (which uses SMO) to script the view. SMO is the full-fidelity scripting engine for all SQL Server objects.
With Powershell you can automate this easilly, eg:
$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()
}
And from Profiler, there's no server-side functionality at work here. SMO fetches the view definition, and has a TSQL parser so it can fix the DDL while scripting the object. Here's the query SMO runs to get the view body:
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)
来源:https://stackoverflow.com/questions/64882963/how-can-i-get-the-definition-of-a-view-with-the-correct-name