如何对 Sql Server 列的默认绑定使用参数化函数
我有一个表,用于对来自多个源的选定文件进行编目。我想在对新文件进行编目时记录文件是否是先前编目文件的重复项。我的表中有一个列(“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
I have a table that catalogs selected files from multiple sources. I want to record whether a file is a duplicate of a previously cataloged file at the time the new file is cataloged. I have a column in my table (“primary_duplicate”) to record each entry as ‘P’ (primary) or ‘D’ (duplicate). I would like to provide a Default Binding for this column that would check for other occurrences of this file (i.e. name, length, timestamp) at the time the new file is being recorded.
I have created a function that performs this check (see “GetPrimaryDuplicate” below). But I don’t know how to bind this function which requires three parameters to the table’s “primary_duplicate” column as its Default Binding.
I would like to avoid using a trigger. I currently have a stored procedure used to insert new records that performs this check. But I would like to ensure that the flag is set correctly if an insert is performed outside of this stored procedure.
How can I call this function with values from the row that is being inserted?
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好的,我是在第一次提出这个问题 2.5 年后发布的,但是:您是否考虑过对
primary_duplicate
列使用计算列,而不是具有默认绑定的常规列?根据 MSDN,“constant_expression DEFAULT 定义不能引用表中的另一列,也不能引用其他表、视图或存储过程。”
另一方面,计算列可以。
将函数定义如下:
然后执行以下 ALTER TABLE 语句:
OK, I'm posting this 2.5 years after the question was first asked, but: have you considered using a calculated column for your
primary_duplicate
column, rather than a regular column with a default binding?According to MSDN, "constant_expression in a DEFAULT definition cannot refer to another column in the table, or to other tables, views, or stored procedures."
A computed column, on the other hand, can.
Define your function as this:
Then execute the following ALTER TABLE statement:
您应该使用触发器。触发器将接收插入行的副本。
You should use a trigger instead. The trigger will receive a copy of the inserted row.
约翰,这不是问题的答案,你认为他应该使用触发器是非常自以为是的。您不知道他想要做什么,也不知道他想要以默认值执行此操作的原因是什么。
如果不可能,你可能会说“那不可能,所以你应该使用触发器”,这样他才能真正学到一些东西。我相信他和你一样了解触发器是什么以及它们的用途。
OP:抱歉,但我正在寻找相同的信息。
John, that isn't an answer to the question, and it's awfully presumptuous of you to assume that he should use a trigger. You don't know what he's trying to do or what reasons he might have for wanting to do it in default value.
If it's not possible, you might have said "That's not possible, so you should use a trigger instead" so he can actually learn something. I'm sure he knows as well as you do what triggers are and what they can be used for.
OP: Sorry, but I'm searching for the same information.