更改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 中在表的计算列中引用的标量函数

sql中表级约束和列级约束

如何对sqlserver2005数据库中表字段进行加密,解密?

SQL Server 2008 - 返回连接条目和“无法绑定多部分标识符”错误的用户定义函数

更改db2 luw中表的列顺序