如何为 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 列的默认绑定使用参数化函数的主要内容,如果未能解决你的问题,请参考以下文章