ورود

View Full Version : رفتار متفاوت یک Constaint در 2000 و 2005



رضا عربلو
دوشنبه 20 اسفند 1386, 21:08 عصر
من یک Constarint به صورت زیر برای تیبلم ساخته ام:


dbo.GetConfilict() = 0

GetConfilict یک فانکشن است.

جالب این است که در اس کیو ال 2005 درست کار می کند. یعنی در صورتی که بخواهم تغییری در دیتابیسم ایجاد کنم که شرط فوق را نقض کند، نمی گذارد تغییری در دیتابیس ام ایجاد شود.
ولی در اس کیو ال 2000 می گذارد اولین تغییری که شرط فوق را نقض می کند اجرا می شود و تغییرات اعمال می شود و پس از آن کلاً تیبل ام قفل می شود و اجازه نمی دهد هیچ تغییر در آن بدهم (حتی پاک کردن تغییراتی که موجب نقض این Constraint شده است). در ضمن اس کیو ال سرور 2000 با sp4 است (2000-2003 + بیلد دو هزار و هفتاد و خورده ای)

AminSobati
سه شنبه 21 اسفند 1386, 23:38 عصر
رضا جان ممکنه سورس این تابع رو ببینیم؟

رضا عربلو
چهارشنبه 22 اسفند 1386, 16:23 عصر
امین جان،
این اسکریپت تیبل ام :


USE [PWKaraTrans]
GO
/****** Object: Table [dbo].[tblPersonnelInformation] Script Date: 02/26/2007 10:28:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tblPersonnelInformation](
[EmployeeNo] [float] NOT NULL,
[Name] [nvarchar](50) NULL,
[Family] [nvarchar](50) NULL,
[CardNo1] [varchar](16) NULL,
[CardNo2] [varchar](16) NULL,
[CardNo3] [varchar](16) NULL,
[CardNo4] [varchar](16) NULL,
CONSTRAINT [PK_tblPersonnelInformation] PRIMARY KEY CLUSTERED
(
[EmployeeNo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[tblPersonnelInformation] WITH CHECK ADD CONSTRAINT [CK_tblPersonnelInformation] CHECK (([dbo].[GetCardsConfilictCounts]()=(0)))
GO
ALTER TABLE [dbo].[tblPersonnelInformation] CHECK CONSTRAINT [CK_tblPersonnelInformation]


این هم اسکریپت فانکشن ام :


USE [PWKaraTrans]
GO
/****** Object: UserDefinedFunction [dbo].[GetCardsConfilictCounts] Script Date: 02/26/2007 10:16:07 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date, ,>
-- Description: <Description, ,>
-- =============================================
CREATE FUNCTION [dbo].[GetCardsConfilictCounts]
(
)
RETURNS INT
AS
BEGIN
DECLARE @ConflictCount INT;
SET @ConflictCount = 0;
SELECT @ConflictCount=COUNT(*)
FROM (SELECT CardNo, COUNT(*) AS Cnt
FROM (SELECT EmployeeNo, Name, Family, CardNo1 AS CardNo, 1 as L
FROM dbo.tblPersonnelInformation
WHERE (CardNo1 IS NOT NULL) AND (LTRIM(RTRIM(CardNo1)) <> '')
UNION
SELECT EmployeeNo, Name, Family, CardNo2 AS CardNo, 2 as L
FROM dbo.tblPersonnelInformation AS tblPersonnelInformation_1
WHERE (CardNo2 IS NOT NULL) AND (LTRIM(RTRIM(CardNo2)) <> '')
UNION
SELECT EmployeeNo, Name, Family, CardNo3 AS CardNo, 3 as L
FROM dbo.tblPersonnelInformation AS tblPersonnelInformation_2
WHERE (CardNo3 IS NOT NULL) AND (LTRIM(RTRIM(CardNo3)) <> '')
UNION
SELECT EmployeeNo, Name, Family, CardNo4 AS CardNo, 4 as L
FROM dbo.tblPersonnelInformation AS tblPersonnelInformation_3
WHERE (CardNo4 IS NOT NULL) AND (LTRIM(RTRIM(CardNo4)) <> '')) AS t1
GROUP BY CardNo
HAVING (COUNT(*) >= 2)) AS t2;
RETURN @ConflictCount;
END


در زیر هم تصویری از آنچه که در اس کیو ال 2000 اتفاق می افتد.
تصویر 1 - ورژن اس کیو ال سرورم.
تصویر 2 - ثبت یک رکورد که کانسترینت ام را نقض کرده است، ولی ثبت شده است.(در کمال تعجب)
تصویر 3 - پاک کردن همان فیلد (و یا هر تغییر دیگر در تیبل) یک خطا Raise مس کند.