SQL 服务器将标识符传递给存储 procedures/dynamic SQL
SQL Server passing identifiers to stored procedures/dynamic SQL
背景:
SQL Server Management Studio
允许定义自己的查询快捷方式 (Tools > Options > Environment > Keyboard > Query Shortcuts
):
my_schema.my_table
-- highlight it
-- press CTRL + 3 and you will get the number of rows in table
它工作正常,但它以基本形式连接查询(据我所知只在最后)。查询:
SELECT COUNT(*) FROM my_schema.my_table;
尝试 #1
现在我想写一些更具体的东西,例如 pass/concatenate table 以下查询的名称(这只是示例):
SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(...)
所以当我在查询快捷方式中写入时:
SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID('
我必须使用:
my_schema.my_table')
-- highlight it
-- press CTRL + 3
额外的')
很丑很不方便
尝试 #2:
二试是用Dynamic-SQL:
EXEC dbo.sp_executesql
N'SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@obj_name)'
,N'@obj_name SYSNAME'
,
正在执行:
my_table
-- highligt it
-- and run
当 table 名称被引用 [my_table]
时也有效。只要对象在 dbo
(默认)架构中。
问题是当 table 有模式时它不会工作:
EXEC dbo.sp_executesql
N'SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@obj_name)'
,N'@obj_name SYSNAME'
,
正在执行:
my_schema.my_table
[my_schema].[my_table]
Incorrect syntax near '.'.
我当然可以写:
EXEC dbo.sp_executesql
N'SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@obj_name)'
,N'@obj_name SYSNAME'
,'
并将其命名为:
[my_schema].[my_table]'
但是额外的'
又丑又不方便
问题:
是否可以传递值,查询快捷方式window,在中间(位置甚至多个值)?
是否可以传递 do stored_procedure/dynamic-sql 限定标识符而不用 '
, "
?
备注:
- 我不搜索 SSMS 插件
- 我不想将 object_name 包装成
"my_schema.my_table"
- 我知道有
sp_helptext
(这只是例子,我搜索方法)
- 第一个问题是特定于工具的(我知道),但第二个问题是关于
SQL Server
。
编辑:
澄清在没有 '
或 "
的情况下将标识符传递给 SP:
CREATE TABLE dbo.my_table(col INT);
GO
CREATE PROCEDURE dbo.my_proc
@a SYSNAME
AS
SELECT *
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@a)
GO
EXEC dbo.my_proc
@a = my_table;
EXEC dbo.my_proc
@a = dbo.my_table;
-- Incorrect syntax near '.'.
1。是否可以在中间传递值,查询快捷方式window?
据我所知,没有实现此目的的解决方法。
1-b。是否可以传递多个值?
可以使用分隔符对字符串值进行操作,然后在另一侧拆分该值。可悲的是,没有很多特殊字符可以完成这项工作,因为它们几乎都会引发语法错误。然而,'#' 可能是一个明智的选择,因为对于进入 tempDB 的 temp table,它已经是 SQL 的特殊字符。只需检查您是否还没有使用它的标识符,因为 SQL 允许它(强硬,它被禁止作为第一个字符)。
这是一个例子:
创建一个存储过程以将参数接收到一个字符串中并将字符串拆分为每个参数。
CREATE PROCEDURE sp_PassingMultipleStringValues
@Param1 NVARCHAR(MAX)
AS
--Here I'm using a XML split, but feel free to use any string split function you already have.
DECLARE @xml AS XML,
@separator AS VARCHAR(1)
SELECT @separator ='#',
@xml = CAST('<X>'+ (REPLACE(@Param1,@separator ,'</X><X>') +'</X>') AS XML)
SELECT N.value('.', 'VARCHAR(200)') AS value
FROM @xml.nodes('X') as T(N)
--Do whatever is needed with them
然后如图所示配置您的快捷方式。 (注意最后的space)
结果:
2。是否可以传递给 stored_procedure/dynamic-sql 限定标识符而不用 ', "?
您是否有多个具有相同标识符的模式?
因为如果不是,那么使用 sys.schemas 而不是传递它在另一端检索它怎么样?
与其在末尾输入不方便的字符,不如输入更少的内容。
使用检索到的架构,您可以根据需要执行动态 SQL。
SELECT @Param1 = REPLACE(REPLACE(@Param1, '[', ''), ']', '')
SELECT TOP 1 @Param1 = [Schema].name + '.' + @Param1
FROM sys.objects AS obj
JOIN sys.schemas AS [Schema] ON obj.schema_id = [Schema].schema_id
WHERE obj.name = @Param1
SELECT *
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@Param1)
DECLARE @Query NVARCHAR(MAX) = 'SELECT TOP 1 * FROM ' + @Param1
EXEC sp_sqlexec @Query
如果您确实想处理两个具有相同标识符的不同模式,那么使用答案 1-b 中解释的方法将模式和标识符作为两个参数传递仍然可行。
一个例子中的一切
因为这里我们要传递多个标识符并指定它们的架构,所以需要两个分隔符。
CREATE PROCEDURE sp_MultiArgsWithSchema
@Param1 NVARCHAR(MAX)
AS
SELECT @Param1 = REPLACE(REPLACE(@Param1, '[', ''), ']', '')
--Here I'm using a XML split, but feel free to use any string split function you already have.
DECLARE @xml AS XML,
@ArgSeparator AS VARCHAR(2),
@SchemaSeparor AS VARCHAR(1)
SELECT @ArgSeparator = '##',
@SchemaSeparor = '#',
@xml = CAST('<X>'+ (REPLACE(@Param1,@ArgSeparator, '</X><X>') +'</X>') AS XML)
IF OBJECT_ID('tempdb..#QualifiedIdentifiers') IS NOT NULL
DROP TABLE #QualifiedIdentifiers;
--While splitting, we are putting back the dot instead of '#' between schema and name of object
SELECT QualifiedIdentifier = REPLACE(N.value('.', 'VARCHAR(200)'), @SchemaSeparor, '.')
INTO #QualifiedIdentifiers
FROM @xml.nodes('X') as T(N)
SELECT * FROM #QualifiedIdentifiers
--From here, use what is inside #QualifiedIdentifiers and Dynamic SQL if need to achieve what is needed
DECLARE @QualifiedIdentifier NVARCHAR(500)
WHILE EXISTS(SELECT TOP 1 1 FROM #QualifiedIdentifiers)
BEGIN
SELECT TOP 1 @QualifiedIdentifier = QualifiedIdentifier
FROM #QualifiedIdentifiers
SELECT *
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@QualifiedIdentifier)
DELETE TOP (1)
FROM #QualifiedIdentifiers
WHERE QualifiedIdentifier = @QualifiedIdentifier
END
用法(请注意,指定架构不是强制性的):
所以,由于必须将拆分字符加倍不方便,所以如果模式可以像上面说的那样被猜到就更好了。
这是一个通过多部分标识符而不用引号引起来的远景。
解法:
查询快捷方式将在数据库中创建一个具有特定名称的同义词和一个DDLTrigger来拦截这个特定的同义词创建。
在查询快捷方式中设置以下快捷方式。 (确保包括最后一个 space)
DECLARE @CreateTriggerSQL NVARCHAR(MAX) = 'CREATE TRIGGER DDLTrigger_QueryShortcutX ON DATABASE FOR CREATE_SYNONYM AS BEGIN DECLARE @EventData XML = EVENTDATA(), @SynonymName NVARCHAR(255), @DbName NVARCHAR(255), @SchemaName NVARCHAR(255), @ObjectName NVARCHAR(255), @Alias NVARCHAR(255) SELECT @SynonymName = @EventData.value(''(/EVENT_INSTANCE/ObjectName)[1]'', ''NVARCHAR(255)'') IF(@SynonymName = ''QueryShortcutX'') BEGIN DROP SYNONYM QueryShortcutX DROP TRIGGER DDLTrigger_QueryShortcutX ON DATABASE SELECT @DbName = @EventData.value(''(/EVENT_INSTANCE/DatabaseName)[1]'', ''NVARCHAR(255)''), @SchemaName = @EventData.value(''(/EVENT_INSTANCE/TargetSchemaName)[1]'', ''NVARCHAR(255)''), @ObjectName = @EventData.value(''(/EVENT_INSTANCE/TargetObjectName)[1]'', ''NVARCHAR(255)''), @Alias = (CASE WHEN LEN(@SchemaName) > 0 THEN @SchemaName + ''.'' ELSE '''' END) + @ObjectName /*EXEC yourStoredProcHere @Param = @Alias*/ SELECT DbName = @DbName, SchemaName = @SchemaName, ObjectName = @ObjectName, Alias = @Alias, ObjectId = OBJECT_ID(@Alias) END END' EXEC sp_executeSQL @CreateTriggerSQL CREATE SYNONYM QueryShortcutX FOR
正如@Vladimir 所建议的,这里我们使用 "sp_executesql" 来同时创建触发器和同义词。
这是没有内联的触发器代码。
CREATE TRIGGER DDLTrigger_QueryShortcutX ON DATABASE FOR CREATE_SYNONYM
AS
BEGIN
DECLARE @EventData XML = EVENTDATA(),
@SynonymName NVARCHAR(255),
@DbName NVARCHAR(255),
@SchemaName NVARCHAR(255),
@ObjectName NVARCHAR(255),
@Alias NVARCHAR(255)
SELECT @SynonymName = @EventData.value('(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(255)')
--Safety in case someone else really create a synonym meanwhile.
IF(@SynonymName = 'QueryShortcutX')
BEGIN
--2. Clean up what we created
DROP SYNONYM QueryShortcutX
DROP TRIGGER DDLTrigger_QueryShortcutX ON DATABASE
--3. Parsing identifier code here
SELECT @DbName = @EventData.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'NVARCHAR(255)'),
@SchemaName = @EventData.value('(/EVENT_INSTANCE/TargetSchemaName)[1]', 'NVARCHAR(255)'),
@ObjectName = @EventData.value('(/EVENT_INSTANCE/TargetObjectName)[1]', 'NVARCHAR(255)'),
@Alias = (CASE WHEN LEN(@SchemaName) > 0 THEN @SchemaName + '.' ELSE '' END) + @ObjectName
--4. Here, write any print/select statement you want.
--For maintenance, it would be easier to just call a stored procedure from here with parameter and put the desired print/select there.
--Thus avoiding to redo inlining the whole trigger each time.
--EXEC yourStoredProcHere @Param = @Alias
SELECT DbName = @DbName,
SchemaName = @SchemaName,
ObjectName = @ObjectName,
Alias = @Alias,
ObjectId = OBJECT_ID(@Alias)
END
END
这里是没有内联的快捷方式代码。
DECLARE @CreateTriggerSQL NVARCHAR(MAX) = 'Trigger creation code here...'
IF EXISTS(SELECT TOP 1 1 FROM sys.triggers WHERE name = 'DDLTrigger_QueryShortcutX')
BEGIN
DROP TRIGGER DDLTrigger_QueryShortcutX ON DATABASE
END
EXEC sp_executeSQL @CreateTriggerSQL
IF EXISTS(SELECT TOP 1 1 FROM sys.synonyms WHERE name = 'QueryShortcutX')
BEGIN
DROP SYNONYM QueryShortcutX
END
CREATE SYNONYM QueryShortcutX FOR
触发器删除自身和同义词以避免模式污染。
- 触发器解析信息以检索标识符。
- 根据您的需要使用标识符。 (如果需要,使用动态 SQL)
每个测试项目的结果
1.RealColumnName
2.WhatEverText
3.dbo.tests
4.[No selection]
5.dbo.tests.very.much
DbName SchemaName ObjectName Alias ObjectId
1.TEST RealColumnName RealColumnName NULL --FN OBJECT_ID doesn't return value with only column name
2.TEST WhatEverText WhatEverText NULL
3.TEST dbo tests dbo.tests 245575913
4.Incorrect syntax near 'FOR'.
5.TEST very much very.much NULL
我所做的解析不能正确处理超过两个多部分的标识符。如果你想改进它。以下 XML 显示要使用的标签。
<TargetServerName>dbo</TargetServerName>
<TargetDatabaseName>tests</TargetDatabaseName>
<TargetSchemaName>very</TargetSchemaName>
<TargetObjectName>much</TargetObjectName>
注:
- 如果您愿意,可以让触发器永久保留在数据库中。
- 另外,如果你想传递多个标识符,像我在其他答案中所做的那样的字符串解析在这里仍然是可能的。
- 要使用此解决方案,用户必须拥有 "create synonym permission" 并且拥有架构或拥有 "ALTER SCHEMA permission".
背景:
SQL Server Management Studio
允许定义自己的查询快捷方式 (Tools > Options > Environment > Keyboard > Query Shortcuts
):
my_schema.my_table
-- highlight it
-- press CTRL + 3 and you will get the number of rows in table
它工作正常,但它以基本形式连接查询(据我所知只在最后)。查询:
SELECT COUNT(*) FROM my_schema.my_table;
尝试 #1
现在我想写一些更具体的东西,例如 pass/concatenate table 以下查询的名称(这只是示例):
SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(...)
所以当我在查询快捷方式中写入时:
SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID('
我必须使用:
my_schema.my_table')
-- highlight it
-- press CTRL + 3
额外的')
很丑很不方便
尝试 #2:
二试是用Dynamic-SQL:
EXEC dbo.sp_executesql
N'SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@obj_name)'
,N'@obj_name SYSNAME'
,
正在执行:
my_table
-- highligt it
-- and run
当 table 名称被引用 [my_table]
时也有效。只要对象在 dbo
(默认)架构中。
问题是当 table 有模式时它不会工作:
EXEC dbo.sp_executesql
N'SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@obj_name)'
,N'@obj_name SYSNAME'
,
正在执行:
my_schema.my_table
[my_schema].[my_table]
Incorrect syntax near '.'.
我当然可以写:
EXEC dbo.sp_executesql
N'SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@obj_name)'
,N'@obj_name SYSNAME'
,'
并将其命名为:
[my_schema].[my_table]'
但是额外的'
又丑又不方便
问题:
是否可以传递值,查询快捷方式window,在中间(位置甚至多个值)?
是否可以传递 do stored_procedure/dynamic-sql 限定标识符而不用
'
,"
?
备注:
- 我不搜索 SSMS 插件
- 我不想将 object_name 包装成
"my_schema.my_table"
- 我知道有
sp_helptext
(这只是例子,我搜索方法) - 第一个问题是特定于工具的(我知道),但第二个问题是关于
SQL Server
。
编辑:
澄清在没有 '
或 "
的情况下将标识符传递给 SP:
CREATE TABLE dbo.my_table(col INT);
GO
CREATE PROCEDURE dbo.my_proc
@a SYSNAME
AS
SELECT *
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@a)
GO
EXEC dbo.my_proc
@a = my_table;
EXEC dbo.my_proc
@a = dbo.my_table;
-- Incorrect syntax near '.'.
1。是否可以在中间传递值,查询快捷方式window?
据我所知,没有实现此目的的解决方法。
1-b。是否可以传递多个值?
可以使用分隔符对字符串值进行操作,然后在另一侧拆分该值。可悲的是,没有很多特殊字符可以完成这项工作,因为它们几乎都会引发语法错误。然而,'#' 可能是一个明智的选择,因为对于进入 tempDB 的 temp table,它已经是 SQL 的特殊字符。只需检查您是否还没有使用它的标识符,因为 SQL 允许它(强硬,它被禁止作为第一个字符)。
这是一个例子:
创建一个存储过程以将参数接收到一个字符串中并将字符串拆分为每个参数。
CREATE PROCEDURE sp_PassingMultipleStringValues
@Param1 NVARCHAR(MAX)
AS
--Here I'm using a XML split, but feel free to use any string split function you already have.
DECLARE @xml AS XML,
@separator AS VARCHAR(1)
SELECT @separator ='#',
@xml = CAST('<X>'+ (REPLACE(@Param1,@separator ,'</X><X>') +'</X>') AS XML)
SELECT N.value('.', 'VARCHAR(200)') AS value
FROM @xml.nodes('X') as T(N)
--Do whatever is needed with them
然后如图所示配置您的快捷方式。 (注意最后的space)
结果:
2。是否可以传递给 stored_procedure/dynamic-sql 限定标识符而不用 ', "?
您是否有多个具有相同标识符的模式?
因为如果不是,那么使用 sys.schemas 而不是传递它在另一端检索它怎么样?
与其在末尾输入不方便的字符,不如输入更少的内容。
使用检索到的架构,您可以根据需要执行动态 SQL。
SELECT @Param1 = REPLACE(REPLACE(@Param1, '[', ''), ']', '')
SELECT TOP 1 @Param1 = [Schema].name + '.' + @Param1
FROM sys.objects AS obj
JOIN sys.schemas AS [Schema] ON obj.schema_id = [Schema].schema_id
WHERE obj.name = @Param1
SELECT *
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@Param1)
DECLARE @Query NVARCHAR(MAX) = 'SELECT TOP 1 * FROM ' + @Param1
EXEC sp_sqlexec @Query
如果您确实想处理两个具有相同标识符的不同模式,那么使用答案 1-b 中解释的方法将模式和标识符作为两个参数传递仍然可行。
一个例子中的一切
因为这里我们要传递多个标识符并指定它们的架构,所以需要两个分隔符。
CREATE PROCEDURE sp_MultiArgsWithSchema
@Param1 NVARCHAR(MAX)
AS
SELECT @Param1 = REPLACE(REPLACE(@Param1, '[', ''), ']', '')
--Here I'm using a XML split, but feel free to use any string split function you already have.
DECLARE @xml AS XML,
@ArgSeparator AS VARCHAR(2),
@SchemaSeparor AS VARCHAR(1)
SELECT @ArgSeparator = '##',
@SchemaSeparor = '#',
@xml = CAST('<X>'+ (REPLACE(@Param1,@ArgSeparator, '</X><X>') +'</X>') AS XML)
IF OBJECT_ID('tempdb..#QualifiedIdentifiers') IS NOT NULL
DROP TABLE #QualifiedIdentifiers;
--While splitting, we are putting back the dot instead of '#' between schema and name of object
SELECT QualifiedIdentifier = REPLACE(N.value('.', 'VARCHAR(200)'), @SchemaSeparor, '.')
INTO #QualifiedIdentifiers
FROM @xml.nodes('X') as T(N)
SELECT * FROM #QualifiedIdentifiers
--From here, use what is inside #QualifiedIdentifiers and Dynamic SQL if need to achieve what is needed
DECLARE @QualifiedIdentifier NVARCHAR(500)
WHILE EXISTS(SELECT TOP 1 1 FROM #QualifiedIdentifiers)
BEGIN
SELECT TOP 1 @QualifiedIdentifier = QualifiedIdentifier
FROM #QualifiedIdentifiers
SELECT *
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@QualifiedIdentifier)
DELETE TOP (1)
FROM #QualifiedIdentifiers
WHERE QualifiedIdentifier = @QualifiedIdentifier
END
用法(请注意,指定架构不是强制性的):
所以,由于必须将拆分字符加倍不方便,所以如果模式可以像上面说的那样被猜到就更好了。
这是一个通过多部分标识符而不用引号引起来的远景。
解法:
查询快捷方式将在数据库中创建一个具有特定名称的同义词和一个DDLTrigger来拦截这个特定的同义词创建。
在查询快捷方式中设置以下快捷方式。 (确保包括最后一个 space)
DECLARE @CreateTriggerSQL NVARCHAR(MAX) = 'CREATE TRIGGER DDLTrigger_QueryShortcutX ON DATABASE FOR CREATE_SYNONYM AS BEGIN DECLARE @EventData XML = EVENTDATA(), @SynonymName NVARCHAR(255), @DbName NVARCHAR(255), @SchemaName NVARCHAR(255), @ObjectName NVARCHAR(255), @Alias NVARCHAR(255) SELECT @SynonymName = @EventData.value(''(/EVENT_INSTANCE/ObjectName)[1]'', ''NVARCHAR(255)'') IF(@SynonymName = ''QueryShortcutX'') BEGIN DROP SYNONYM QueryShortcutX DROP TRIGGER DDLTrigger_QueryShortcutX ON DATABASE SELECT @DbName = @EventData.value(''(/EVENT_INSTANCE/DatabaseName)[1]'', ''NVARCHAR(255)''), @SchemaName = @EventData.value(''(/EVENT_INSTANCE/TargetSchemaName)[1]'', ''NVARCHAR(255)''), @ObjectName = @EventData.value(''(/EVENT_INSTANCE/TargetObjectName)[1]'', ''NVARCHAR(255)''), @Alias = (CASE WHEN LEN(@SchemaName) > 0 THEN @SchemaName + ''.'' ELSE '''' END) + @ObjectName /*EXEC yourStoredProcHere @Param = @Alias*/ SELECT DbName = @DbName, SchemaName = @SchemaName, ObjectName = @ObjectName, Alias = @Alias, ObjectId = OBJECT_ID(@Alias) END END' EXEC sp_executeSQL @CreateTriggerSQL CREATE SYNONYM QueryShortcutX FOR
正如@Vladimir 所建议的,这里我们使用 "sp_executesql" 来同时创建触发器和同义词。
这是没有内联的触发器代码。
CREATE TRIGGER DDLTrigger_QueryShortcutX ON DATABASE FOR CREATE_SYNONYM AS BEGIN DECLARE @EventData XML = EVENTDATA(), @SynonymName NVARCHAR(255), @DbName NVARCHAR(255), @SchemaName NVARCHAR(255), @ObjectName NVARCHAR(255), @Alias NVARCHAR(255) SELECT @SynonymName = @EventData.value('(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(255)') --Safety in case someone else really create a synonym meanwhile. IF(@SynonymName = 'QueryShortcutX') BEGIN --2. Clean up what we created DROP SYNONYM QueryShortcutX DROP TRIGGER DDLTrigger_QueryShortcutX ON DATABASE --3. Parsing identifier code here SELECT @DbName = @EventData.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'NVARCHAR(255)'), @SchemaName = @EventData.value('(/EVENT_INSTANCE/TargetSchemaName)[1]', 'NVARCHAR(255)'), @ObjectName = @EventData.value('(/EVENT_INSTANCE/TargetObjectName)[1]', 'NVARCHAR(255)'), @Alias = (CASE WHEN LEN(@SchemaName) > 0 THEN @SchemaName + '.' ELSE '' END) + @ObjectName --4. Here, write any print/select statement you want. --For maintenance, it would be easier to just call a stored procedure from here with parameter and put the desired print/select there. --Thus avoiding to redo inlining the whole trigger each time. --EXEC yourStoredProcHere @Param = @Alias SELECT DbName = @DbName, SchemaName = @SchemaName, ObjectName = @ObjectName, Alias = @Alias, ObjectId = OBJECT_ID(@Alias) END END
这里是没有内联的快捷方式代码。
DECLARE @CreateTriggerSQL NVARCHAR(MAX) = 'Trigger creation code here...' IF EXISTS(SELECT TOP 1 1 FROM sys.triggers WHERE name = 'DDLTrigger_QueryShortcutX') BEGIN DROP TRIGGER DDLTrigger_QueryShortcutX ON DATABASE END EXEC sp_executeSQL @CreateTriggerSQL IF EXISTS(SELECT TOP 1 1 FROM sys.synonyms WHERE name = 'QueryShortcutX') BEGIN DROP SYNONYM QueryShortcutX END CREATE SYNONYM QueryShortcutX FOR
触发器删除自身和同义词以避免模式污染。
- 触发器解析信息以检索标识符。
- 根据您的需要使用标识符。 (如果需要,使用动态 SQL)
每个测试项目的结果
1.RealColumnName
2.WhatEverText
3.dbo.tests
4.[No selection]
5.dbo.tests.very.much
DbName SchemaName ObjectName Alias ObjectId
1.TEST RealColumnName RealColumnName NULL --FN OBJECT_ID doesn't return value with only column name
2.TEST WhatEverText WhatEverText NULL
3.TEST dbo tests dbo.tests 245575913
4.Incorrect syntax near 'FOR'.
5.TEST very much very.much NULL
我所做的解析不能正确处理超过两个多部分的标识符。如果你想改进它。以下 XML 显示要使用的标签。
<TargetServerName>dbo</TargetServerName>
<TargetDatabaseName>tests</TargetDatabaseName>
<TargetSchemaName>very</TargetSchemaName>
<TargetObjectName>much</TargetObjectName>
注:
- 如果您愿意,可以让触发器永久保留在数据库中。
- 另外,如果你想传递多个标识符,像我在其他答案中所做的那样的字符串解析在这里仍然是可能的。
- 要使用此解决方案,用户必须拥有 "create synonym permission" 并且拥有架构或拥有 "ALTER SCHEMA permission".