更改Sql server中表列使用的用户定义函数体
Posted
技术标签:
【中文标题】更改Sql server中表列使用的用户定义函数体【英文标题】:Change user-defined function body used by a table column in Sql server 【发布时间】:2013-10-02 10:51:44 【问题描述】:我有一个表 dnn_Files 和用户定义的函数列文件夹:
CREATE TABLE [dnn_Files](
...
[Folder] AS ([GetFileFolderFunc]([FolderID])),
...
...
该数据库是通过 dotnetnuke 安装创建并使用的。所以,它不是空的。
我真正的目标是在数据库中添加“dnn_”对象限定符(原始数据库有空限定符)。
为了存档,我重命名了所有 dnn 表,删除了存储过程,用户定义的函数(GetFileFolderFunc 除外 - 因为它被 dnn_Files 引用,所以无法删除),查看并使用正确的对象限定符重新创建它。
之后,我得到了如上所述的表格。该表具有正确的限定符,而 GetFileFolderFunc 没有。由于表已重命名,GetFileFolderFunc 现在指的是不存在的表。带有限定符(dnn_GetFileFolderFunc) 的正确双胞胎在数据库中。
所以,我希望 dnn_Files 使用新的 dnn_GetFileFolderFunc 函数。
当我尝试更改文件夹列(通过 Sql Management Studio 设计器更改计算列规范)时,它失败并显示错误“不允许保存更改。您所做的更改需要 dnn_Files 是 dropper 并重新创建.. ."。由于 dnn_Files 有很多关系,它不能被删除。似乎合乎逻辑。
然后我尝试更改 GetFileFolderFunc 的主体以使用具有新对象限定符的表,但也没有运气。错误是“Cannot ALTER 'dbo.GetFileFolderFunc' 因为它被对象 'dnn_Files' 引用”。
对于第一个或第二个限制是否有任何变通方法?
Sql 服务器版本:11.0.2100.60
【问题讨论】:
尝试使用 SQL alter 命令而不是使用 SSMS UI 执行 ALTER。 如果没有,您可能需要删除/创建并重新填充 dnn_Files 中的数据。在尝试这样的事情之前,请始终进行完整的数据库备份。 @L_7337,谢谢。我为此写了一个答案。 【参考方案1】:ALTER TABLE dbo.dnn_Files DROP COLUMN Folder;
GO
ALTER TABLE dbo.dnn_Files ADD Folder AS ([dbo].[dnn_GetFileFolderFunc]([FolderID]));
欢迎您@mt_serg。如果你想给我信用,请接受这个答案。我只是有点忙于其他事情,无法写出一个好的、完整的答案。
【讨论】:
【参考方案2】:L_7337 是对的,只是使用 SSMS UI 的问题。
Sql修改:
ALTER TABLE dbo.dnn_Files DROP COLUMN Folder;
GO
ALTER TABLE dbo.dnn_Files ADD Folder AS ([dbo].[dnn_GetFileFolderFunc]([FolderID]));
工作正常。非常感谢!
在我看到评论之前,我以另一种方式解决了问题。所以,我决定回答我自己的问题,因为它可能对某人有用。
我通过 bacpac 做到了这一点。解压后(bacpac 只是一个 zip)我修改了 model.xml。相关部分在这里:
<Element Type="SqlComputedColumn" Name="[dbo].[dnn_Files].[Folder]">
<Property Name="ExpressionScript">
<Value><![CDATA[([dbo].[dnn_GetFileFolderFunc]([FolderID]))]]></Value>
</Property>
<Relationship Name="ExpressionDependencies">
<Entry>
<References Name="[dbo].[dnn_GetFileFolderFunc]" />
</Entry>
<Entry>
<References Name="[dbo].[dnn_Files].[FolderID]" />
</Entry>
</Relationship>
</Element>
然后拉回并使用DacChkSum.exe 计算校验和。
>dacchksum /InputFilename:database.bacpac
Model checksum
Stored: :[5745242756E4D7CAD12C913058A1078BC1A5FA5A069C7CC0CF417719F2A64196]
Calculated:[A2B39E19E2219E05B3B4F8DC95A1B764B7A91ABBA9C70D18EAA4247B76120BB0]
在 Origin.xml 中更改校验和后,我刚刚恢复了数据库。
这似乎是向麻雀发射大炮。但是有一个好处,该列保持其顺序,而更改后它成为最新的。我不希望改变大小写有任何副作用,但是在 bacpac 技巧数据库看起来更加一致之后。
【讨论】:
感谢 DacChkSum 的提示。校验和似乎是 SHA256(使用System.Security.Cryptography.SHA256CryptoServiceProvider
)。【参考方案3】:
-
将“dbo.GetFileFolderFunc”脚本创建为新选项卡。更改函数名称并运行脚本。
更改 dnn_files 表以引用新函数。
改变原来的功能。
更改 dnn_files 表以引用现在已更改的原始函数。
删除不再被任何东西引用的新函数。
【讨论】:
以上是关于更改Sql server中表列使用的用户定义函数体的主要内容,如果未能解决你的问题,请参考以下文章
根据 SQL Server 2008R2 中表中的列获取计数
更改 SQL Server 2008 中在表的计算列中引用的标量函数
如何对sqlserver2005数据库中表字段进行加密,解密?