从另一个存储过程调用 sp_addextendedproperty 时出错
Posted
技术标签:
【中文标题】从另一个存储过程调用 sp_addextendedproperty 时出错【英文标题】:Error when calling sp_addextendedproperty from another stored procedure 【发布时间】:2017-01-31 10:25:47 【问题描述】:我尝试将扩展属性添加到我的表和列,但由于 SQL Server 将添加和更新存储过程分开,并且我的情况需要太多未使用的参数,所以我决定为这两个存储过程创建包装器,这样我就可以创建描述只需要在表和列级别添加或更新 3 个参数。这是我当前的代码:
CREATE PROCEDURE sp_addorupdatedesc
@tableName varchar,
@columnName varchar = NULL,
@objectDescription varchar
AS
BEGIN
IF (@columnName IS NULL)
BEGIN
IF NOT EXISTS (SELECT 1 FROM fn_listextendedproperty (NULL, 'user', 'dbo', 'table', default, NULL, NULL) WHERE OBJNAME=@tableName)
BEGIN
EXECUTE sp_addextendedproperty 'MY_DESCRIPTION', @objectDescription, 'user', dbo, 'table', @tableName, default, NULL
END
ELSE
BEGIN
EXECUTE sp_updateextendedproperty 'MY_DESCRIPTION', @objectDescription, 'user', dbo, 'table', @tableName, default, NULL
END
END
ELSE
BEGIN
IF NOT EXISTS (SELECT 1
FROM sys.extended_properties AS ep
INNER JOIN sys.tables AS t ON ep.major_id = t.object_id
INNER JOIN sys.columns AS c ON ep.major_id = c.object_id AND ep.minor_id = c.column_id
WHERE class = 1 AND T.NAME=@tableName AND C.name = @columnName)
BEGIN
EXECUTE sp_addextendedproperty 'MY_DESCRIPTION', @objectDescription, 'user', dbo, 'table', @tableName, 'column', @columnName
END
ELSE
BEGIN
EXECUTE sp_updateextendedproperty 'MY_DESCRIPTION', @objectDescription, 'user', dbo, 'table', @tableName, 'column', @columnName
END
END
END
GO
但是当我使用这个存储过程时,我得到了这个错误:
消息 15135,级别 16,状态 8,过程 sp_addextendedproperty,第 58 行 对象无效。 'dbo.P.P' 上不允许扩展属性,或者该对象不存在。
【问题讨论】:
旁注:您应该不为您的存储过程使用sp_
前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免 sp_
并使用其他东西作为前缀 - 或者根本不使用前缀!
感谢您的建议
Bad habits to kick : declaring VARCHAR without (length) - 您应该始终为您使用的任何varchar
变量和参数提供一个长度。当您将 parameter 定义为 varchar
- 没有任何长度 - 它默认为 EXACTLY 1 CHARACTER 长度 - 通常 NOT 您想要的!所以总是使用长度!!因此,您的表名和列名以及描述都会截断为单个字符!
啊......所以这个错误是因为大小......在我改变了这个 sp 的 varchar 的大小之后!再次感谢您的另一个建议:D
【参考方案1】:
我按照 marc_S 的建议更改了我的存储过程,它现在可以工作了。
这可能是一个笨拙的错误,但我希望如果有人需要在一个存储过程中简化向表或列添加或更新扩展属性,只有 3 个参数“TableName”、“ColumnName”、“Description”。
这里是代码。
CREATE PROCEDURE setdescription
@tableName varchar(100),
@columnName varchar(100) = NULL,
@objectDescription varchar(250)
AS
BEGIN
IF (@columnName IS NULL)
BEGIN
IF NOT EXISTS (SELECT 1 FROM fn_listextendedproperty (NULL, 'user', 'dbo', 'table', default, NULL, NULL) WHERE OBJNAME=@tableName)
BEGIN
EXECUTE sp_addextendedproperty 'MY_DESCRIPTION', @objectDescription, 'user', dbo, 'table', @tableName, default, NULL
END
ELSE
BEGIN
EXECUTE sp_updateextendedproperty 'MY_DESCRIPTION', @objectDescription, 'user', dbo, 'table', @tableName, default, NULL
END
END
ELSE
BEGIN
IF NOT EXISTS (SELECT 1 FROM sys.extended_properties AS ep
INNER JOIN sys.tables AS t ON ep.major_id = t.object_id
INNER JOIN sys.columns AS c ON ep.major_id = c.object_id AND ep.minor_id = c.column_id
WHERE class = 1 AND T.NAME=@tableName AND C.name = @columnName)
BEGIN
EXECUTE sp_addextendedproperty 'MY_DESCRIPTION', @objectDescription, 'user', dbo, 'table', @tableName, 'column', @columnName
--EXECUTE sp_addextendedproperty @name=N'CXC_DESCRIPTION', @value=N@temp3, @level0type=N'user', @level0name=N'dbo', @level1type=N'table', @level1name=N@temp1, @level2type=N'column', @level2name=N@temp2
END
ELSE
BEGIN
EXECUTE sp_updateextendedproperty 'MY_DESCRIPTION', @objectDescription, 'user', dbo, 'table', @tableName, 'column', @columnName
END
END
END
GO
【讨论】:
以上是关于从另一个存储过程调用 sp_addextendedproperty 时出错的主要内容,如果未能解决你的问题,请参考以下文章
从另一个存储过程调用具有交叉应用的存储过程会产生错误 SQL 服务器