如何为 Sql Server 列的默认绑定使用参数化函数

Posted

技术标签:

【中文标题】如何为 Sql Server 列的默认绑定使用参数化函数【英文标题】:how to use a parameterized function for the Default Binding of a Sql Server column 【发布时间】:2010-03-27 05:56:30 【问题描述】:

我有一个表格,可以对来自多个来源的选定文件进行编目。我想在对新文件进行编目时记录文件是否与以前编目的文件重复。我的表中有一个列(“primary_duplicate”),将每个条目记录为“P”(主要)或“D”(重复)。我想为此列提供一个默认绑定,以便在记录新文件时检查该文件的其他事件(即名称、长度、时间戳

我创建了一个执行此检查的函数(请参阅下面的“GetPrimaryDuplicate”)。但是我不知道如何将这个需要三个参数的函数绑定到表的“primary_duplicate”列作为其默认绑定。

我想避免使用触发器。我目前有一个用于插入执行此检查的新记录的存储过程。但如果在此存储过程之外执行插入,我想确保正确设置标志。

如何使用正在插入的行中的值调用此函数?

USE [MyDatabase]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[FileCatalog](
    [id] [uniqueidentifier] NOT NULL,
    [catalog_timestamp] [datetime] NOT NULL,
    [primary_duplicate] [nchar](1) NOT NULL,
    [name] [nvarchar](255) NULL,
    [length] [bigint] NULL,
    [timestamp] [datetime] NULL
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[FileCatalog] ADD  CONSTRAINT [DF_FileCatalog_id]  DEFAULT (newid()) FOR [id]
GO

ALTER TABLE [dbo].[FileCatalog] ADD  CONSTRAINT [DF_FileCatalog_catalog_timestamp]  DEFAULT (getdate()) FOR [catalog_timestamp]
GO

ALTER TABLE [dbo].[FileCatalog] ADD  CONSTRAINT [DF_FileCatalog_primary_duplicate]  DEFAULT (N'GetPrimaryDuplicate(name, length, timestamp)') FOR [primary_duplicate]
GO


USE [MyDatabase]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION [dbo].[GetPrimaryDuplicate] 
(
    @name nvarchar(255),
    @length bigint,
    @timestamp datetime
)
RETURNS nchar(1)
AS 
BEGIN

    DECLARE @c int

    SELECT @c = COUNT(*)
    FROM FileCatalog
    WHERE name=@name and length=@length and timestamp=@timestamp and primary_duplicate = 'P'

    IF @c > 0
        RETURN 'D' -- Duplicate

    RETURN 'P' -- Primary

END

GO

【问题讨论】:

对于糟糕的代码格式,我深表歉意 - 不知道为什么某些代码未包含在格式中 - 也不知道如何更正它。 【参考方案1】:

约翰,这不是问题的答案,你认为他应该使用触发器是非常冒昧的。你不知道他想做什么,也不知道他可能有什么理由想要默认做这件事。

如果不可能,你可能会说“那不可能,所以你应该改用触发器”,这样他才能真正学到一些东西。我相信他和你一样知道触发器是什么以及它们可以用来做什么。

OP:抱歉,我正在搜索相同的信息。

【讨论】:

【参考方案2】:

好的,我在第一次提出问题 2.5 年后发布了这篇文章,但是:您是否考虑过为您的 primary_duplicate 列使用计算列,而不是使用默认绑定的常规列?

根据MSDN,“DEFAULT 定义中的 constant_expression 不能引用表中的另一列,也不能引用其他表、视图或存储过程。”

另一方面,计算列可以。

这样定义你的函数:

CREATE FUNCTION [dbo].[GetPrimaryDuplicate] 
(
   @id  uniqueidentifier,
   @catalog_timestamp datetime,
   @name nvarchar(255),
   @length bigint,
   @timestamp datetime    
)
RETURNS nchar(1)
AS 
BEGIN

IF EXISTS (
    SELECT  1
    FROM    FileCatalog
    WHERE   name=@name and length=@length and timestamp=@timestamp 
        and catalog_timestamp < @catalog_timestamp
)
    RETURN 'D' -- Duplicate

  RETURN 'P' -- Primary

END

然后执行下面的 ALTER TABLE 语句:

GO
ALTER TABLE [dbo].[FileCatalog] DROP   COLUMN primary_duplicate 
ALTER TABLE [dbo].[FileCatalog] ADD    primary_duplicate as dbo.GetPrimaryDuplicate(id, catalog_timestamp, name, length, timestamp)

【讨论】:

【参考方案3】:

您应该改用触发器。触发器将接收插入行的副本。

【讨论】:

以上是关于如何为 Sql Server 列的默认绑定使用参数化函数的主要内容,如果未能解决你的问题,请参考以下文章

如何为 SQL Server 访问配置 ngrok

在sql创建数据库表时,如何为字段设一个默认值

如何用sql实现自动填充日期

如何为SQL Server2008添加登录账户并配置权限

如果绑定源为null,如何为Image设置默认源?

在 SQL 中,如何为另一列的每个不同值创建新的值列?