UPDATE doesn't allow to INSERT null in FK field - sql-server

I have a SQL Server database and in a table there's a lookup column which is a "nullable FK" linked to a master table.
There's a data import process in which we fetch data from table01_staging into table01. This is the UPDATE statement which is failing (if CarrierID is null) -
DECLARE #code as nvarchar(10); SET #code = 'xyz';
UPDATE table01
SET CarrierID = t2.CarrierID
FROM table01 AS t1
INNER JOIN table01_staging AS t2 ON t1.Code = #code;
WHERE t1.Code = #code;
It goes fine if the CarrierID is not null. In fact I can successfully execute:
UPDATE table01
SET CarrierID = null
WHERE t1.Code = 'xyz';
So setting null is not the problem but it doesn't work when its updated from the staging table which has a null value. How can I make it right?
Error : The UPDATE statement conflicted with the FOREIGN KEY constraint FK_table01_MasterCarrier. The conflict occurred in database table01, table dbo.MasterCarrier, column ID.
> EDIT 02: DONE!. Updated the first SQL to show my variable usage - which I believe was the culprit. Correcting the JOIN operation as follows with a COLLATion conversion error fix makes it work -
DECLARE #code as nvarchar(10); SET #code = 'xyz';
UPDATE table01
SET CarrierID = t2.CarrierID
FROM table01 AS t1
INNER JOIN table01_staging AS t2 ON t1.Code = t2.code COLLATE SQL_Latin1_General_CP1_CI_AS
WHERE t1.Code = #code;
Thank you all, esp. Zhang. I deserve a -1 for not being able to understand the JOIN clause properly :-)

Does table01_staging have the same Foreign Key Constraint on CarrierID?
If not, check whether there are some CarrierID not existing in MasterCarrier table.
select * from table01_staging t
where not exists (select 1 from MasterCarrier m where m.ID = t.CarrierID)
!!UPDATE!!
I created the sample table and data. It worked without any issue.
CREATE TABLE [dbo].MasterCarrier(
[id] [int] IDENTITY NOT NULL,
[NAME] [varchar](10) NULL,
CONSTRAINT [PK_mastertable] PRIMARY KEY CLUSTERED
(
[id] ASC
)
)
GO
CREATE TABLE [dbo].[table01](
[id] [int] NOT NULL,
[CarrierID] [int] NULL,
[Code] [varchar](10) NULL
)
GO
ALTER TABLE [dbo].table01 WITH CHECK ADD CONSTRAINT [FK_table01_MasterCarrier] FOREIGN KEY([CarrierID])
REFERENCES [dbo].[MasterCarrier] ([id])
GO
ALTER TABLE [dbo].table01 CHECK CONSTRAINT [FK_table01_MasterCarrier]
GO
CREATE TABLE [dbo].[table01_staging](
[id] [int] NOT NULL,
[CarrierID] [int] NULL,
[Code] [varchar](10) NULL
)
GO
--Insert sample data
INSERT INTO MasterCarrier (NAME) VALUES ('carrier');
INSERT INTO table01 (id, CarrierID, Code) VALUES (1, 1, 'abc'), (2, NULL, 'abc'),(3, 1, 'ddd');
INSERT INTO table01_staging (id, CarrierID, Code) VALUES (1, 1, 'abc'), (2, NULL, 'abc'),(3, 1, 'ddd');
UPDATE table01
SET CarrierID=t2.CarrierID
FROM table01 AS t1
INNER JOIN table01_staging AS t2 ON t1.ID = t2.ID
WHERE t1.Code='abc'
It gets (2 rows affected) message.

Related

After adding Feature Name and Feature Value query takes more than 5 minutes

I work on SQL Server 2014 and my issue occurred after displaying Feature Name and Feature Value separated by $.
When executing the query below after adding Feature Name and Feature Value with stuff it became very slow.
How to enhance it?
Before adding the two stuff statements it took 28 seconds to display 750 thousand records. Now as below script and after adding two stuff statements take 5 minutes.
Script below give me expected result but issue is performance is very slow.
So can I do separate Feature Name and Feature Value to make it faster? Separated by $ if possible.
My script:
IF OBJECT_ID('[dbo].[gen]') IS NOT NULL
DROP TABLE [dbo].[gen]
IF OBJECT_ID('[dbo].[PartAttributes]') IS NOT NULL
DROP TABLE [dbo].[PartAttributes]
IF OBJECT_ID('dbo.core_datadefinition_Detailes') IS NOT NULL
DROP TABLE core_datadefinition_Detailes
CREATE TABLE core_datadefinition_Detailes
(
[ID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[ColumnName] [nvarchar](500) NOT NULL,
[ColumnNumber] [int] NOT NULL,
CONSTRAINT [PK_Core_DataDefinition_Details]
PRIMARY KEY CLUSTERED ([ID] ASC)
)
INSERT INTO core_datadefinition_Detailes([ColumnNumber],[ColumnName])
VALUES (202503, 'Product Shape Type'),
(1501170111, 'Type'),
(202504, 'Package Family')
CREATE TABLE [dbo].[gen]
(
[TradeCodeControlID] [int] IDENTITY(1,1) NOT NULL,
[CodeTypeID] [int] NULL,
[RevisionID] [bigint] NULL,
[Code] [varchar](20) NULL,
[ZPLID] [int] NULL,
[ZfeatureKey] [bigint] NULL,
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[gen] ON
INSERT INTO [dbo].[gen] ([TradeCodeControlID], [CodeTypeID],[RevisionID], [Code], [ZPLID], [ZfeatureKey])
VALUES (7565, 849774, 307683692, N'8541100050', 4239, 202503)
INSERT INTO [dbo].[gen] ([TradeCodeControlID], [CodeTypeID],[RevisionID], [Code], [ZPLID], [ZfeatureKey])
VALUES (7566, 849774, 307683692, N'8541100050', 4239, 202504)
INSERT INTO [dbo].[gen] ([TradeCodeControlID], [CodeTypeID],[RevisionID], [Code], [ZPLID], [ZfeatureKey])
VALUES (7567, 849774, 307683692, N'8541100050', 4239, 1501170111)
SET IDENTITY_INSERT [dbo].[gen] OFF
CREATE TABLE [dbo].[PartAttributes]
(
[PartID] [int] NOT NULL,
[ZfeatureKey] [bigint] NULL,
[AcceptedValuesOption_Value] [float] NULL,
[FeatureValue] [nvarchar](500) NOT NULL
) ON [PRIMARY]
GO
INSERT INTO [dbo].[PartAttributes] ([PartID], [ZfeatureKey], [FeatureValue])
VALUES (413989, 202503, N'Discrete')
INSERT INTO [dbo].[PartAttributes] ([PartID], [ZfeatureKey], [FeatureValue])
VALUES (413989, 1501170111, N'Zener')
INSERT INTO [dbo].[PartAttributes] ([PartID], [ZfeatureKey], [FeatureValue])
VALUES (413989, 202504, N'SOT')
SELECT
PartID, Code, Co.CodeTypeID, Co.RevisionID, Co.ZPLID,
COUNT(1) AS ConCount,
STUFF((SELECT '$' + CAST(CP.ColumnName AS VARCHAR(300)) AS [text()]
FROM
(SELECT DISTINCT
d.ColumnName, C.codeTypeId, C.Code, C.ZfeatureKey
FROM gen C
INNER JOIN core_datadefinitiondetails d WITH (NOLOCK) ON C.ZfeatureKey = d.columnnumber
INNER JOIN PartAttributes P ON P.partid = PM.partid) CP
WHERE CP.codeTypeId = Co.codeTypeId AND CP.Code = Co.Code
ORDER BY CP.ZfeatureKey
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS FeatureName,
STUFF((SELECT '$' + CAST(CP2.FeatureValue AS VARCHAR(300)) AS [text()]
FROM
(SELECT DISTINCT
P.FeatureValue, C2.codeTypeId, C2.Code, C2.ZfeatureKey
FROM gen C2
INNER JOIN PartAttributes P ON C2.ZfeatureKey = P.ZfeatureKey) CP2
WHERE CP2.codeTypeId = Co.codeTypeId AND CP2.Code = Co.Code
ORDER BY CP2.ZfeatureKey
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS FeatureValue
FROM
PartAttributes PM
INNER JOIN
gen Co ON Co.ZfeatureKey = PM.ZfeatureKey
GROUP BY
PartID, Code, Co.CodeTypeID, Co.RevisionID, Co.ZPLID
Final result:
final result after add two stuff

Compare two child table items with two similar parent tables from two databases

I need help creating a query to compare the Equipment in one database to Asset in another table. Here is my database setup:
CREATE DATABASE database1
GO
USE [database1]
GO
CREATE TABLE [dbo].[Application]
(
[ApplicationID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[APP_NUMBRER] [int] NULL,
)
GO
CREATE TABLE [dbo].[Equipment]
(
[EquipID] [int] IDENTITY(1,1) NOT NULL,
[ApplicationID] [int] NULL,
[Year] [varchar](4) NULL,
[Make] [varchar](50) NULL,
[Model] [varchar](50) NULL
)
ALTER TABLE [dbo].[Equipment] WITH CHECK
ADD CONSTRAINT [FK_EQUIP_1]
FOREIGN KEY([ApplicationID]) REFERENCES [dbo].[APPLICATION] ([ApplicationID])
GO
INSERT INTO [Application]
VALUES (1), (2), (3)
INSERT INTO [Equipment]
VALUES (1, '1998', 'Equip1', 'Model1'),
(1, '1855', 'Equip2', 'Model2'),
(2, '1222', 'Equip3', 'Model4'),
(2, '1333', 'Equip4', 'Model4'),
(3, '1777', 'Equip5', 'Model5')
GO
CREATE DATABASE database2
GO
USE [database2]
GO
CREATE TABLE [dbo].[Application]
(
[APP_KEY] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[APP_DESCRIPTION] [varchar](40) NOT NULL
)
GO
CREATE TABLE [dbo].[ASSET]
(
[AS_KEY] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[AS_APP_FKEY] [int] NOT NULL,
[Year] [varchar](4) NULL,
[Make] [varchar](50) NULL,
[Model] [varchar](50) NULL
)
ALTER TABLE [dbo].[ASSET] WITH CHECK
ADD CONSTRAINT [FK_ASSET_1]
FOREIGN KEY([AS_APP_FKEY]) REFERENCES [dbo].[APPLICATION] ([APP_KEY])
GO
INSERT INTO [Application]
VALUES ('AppDesc1'), ('AppDesc2')
INSERT INTO [ASSET]
VALUES (1, '1998', 'Asset1', 'Db2Model1'),
(1, '1855', 'Asset2', 'Db2Model2'),
(2, '1222', 'Asset3', 'Db2Model3'),
(2, '1333', 'Asset4', 'Db2Model4')
GO
My query:
SELECT
ap1.APP_NUMBRER,
e.Year, e.Make, e.Model,
db2.APP_KEY, db2.Year, db2.Make, db2.Model
FROM
database1.dbo.Application ap1
JOIN
database1.dbo.Equipment e ON E.APPLICATIONID = ap1.APPLICATIONID
LEFT JOIN
(SELECT
APP_KEY, Year, Make, Model
FROM
[database2].dbo.APPLICATION ap2
JOIN
[database2].dbo.ASSET ON asset.AS_APP_FKEY = ap2.APP_KEY) db2 ON ap1.APP_NUMBRER = db2.APP_KEY
Result:
Expected result: my query is creating a few duplicate items that compare all of db1 equipment to db2 assets. I want a one to one comparison. I don't want items 2,3,6,7. Is this because of how the table relationships are set up.
It's because you're only joining on APP_NUMBER=APP_KEY. Add Year=Year to the JOIN and you will get your desired result.
Add YEAR in you join. It will solve your problem.
SELECT ap1.APP_NUMBRER, e.Year, e.Make, e.Model, db2.APP_KEY, db2.Year, db2.Make, db2.Model
FROM database1.dbo.Application ap1
JOIN database1.dbo.Equipment e
ON E.APPLICATIONID = ap1.APPLICATIONID
LEFT JOIN(
SELECT APP_KEY, Year, Make, Model
FROM [database2].dbo.APPLICATION ap2
JOIN [database2].dbo.ASSET
ON asset.AS_APP_FKEY = ap2.APP_KEY
) db2
ON ap1.APP_NUMBRER = db2.APP_KEY AND e.Year = db2.Year
Amend your JOIN condition like so
db2 ON ap1.APP_NUMBRER = db2.APP_KEY
AND e.Year = db2.Year

T-SQL ISNULL() incorrect behaviour with reserved word 'Primary' (SQL Server 2014)

I came across this the other day, and it wasn't a major as I could work around it, but wondered if anyone could offer any insight, or have I found an obscure bug?
We have an old database table that has a column called Primary, which is obviously a reserved word. When running a T-SQL query I came across some weird results which seems to suggest that the ISNULL function is treating the column name as if it were the reserved word. Is it just because it's late on Friday and I'm missing something really obvious here, or is something weird going on here?
Here is some simple SQL to set up a couple of test tables to illustrate it.
CREATE TABLE [dbo].[Customer]
(
[CustomerID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
CONSTRAINT [PK_Customer]
PRIMARY KEY CLUSTERED ([CustomerID] ASC)
) ON [PRIMARY]
CREATE TABLE [dbo].[OrderTaken]
(
[OrderID] [int] IDENTITY(1,1) NOT NULL,
[Description] [varchar](50) NOT NULL,
[CustomerID] [int] NOT NULL,
[Primary] [bit] NOT NULL,
CONSTRAINT [PK_Order]
PRIMARY KEY CLUSTERED ([OrderID] ASC)
) ON [PRIMARY]
ALTER TABLE [dbo].[OrderTaken] WITH CHECK
ADD CONSTRAINT [FK_Order_Customer]
FOREIGN KEY([CustomerID]) REFERENCES [dbo].[Customer] ([CustomerID])
GO
ALTER TABLE [dbo].[OrderTaken] CHECK CONSTRAINT [FK_Order_Customer]
GO
INSERT INTO [dbo].[Customer](Name) VALUES('Bob')
INSERT INTO [dbo].[Customer](Name) VALUES('Dave')
INSERT INTO [dbo].[Customer](Name) VALUES('Fred')
INSERT INTO [dbo].[Customer](Name) VALUES('Paul')
GO
INSERT INTO [dbo].[OrderTaken](Description, CustomerID, [Primary])
VALUES ('Order1', 1, 1)
INSERT INTO [dbo].[OrderTaken](Description, CustomerID, [Primary])
VALUES('Order2', 2, 1)
INSERT INTO [dbo].[OrderTaken](Description, CustomerID, [Primary])
VALUES('Order3', 2, 1)
INSERT INTO [dbo].[OrderTaken](Description, CustomerID, [Primary])
VALUES('Order4', 3, 0)
INSERT INTO [dbo].[OrderTaken](Description, CustomerID, [Primary])
VALUES('Order5', 3, 0)
Go
and here is the query
SELECT
C.CustomerID, C.Name,
O.OrderID, ISNULL(O.[OrderID], -1),
O.[Primary], ISNULL(O.[Primary], -1) as Weird
FROM
Customer C
LEFT JOIN
OrderTaken O ON C.CustomerID = O.CustomerID
Notice that for the customer row that doesn't have an Order, O.Primary is NULL , but ISNULL(O.[Primary],-1) returns 1 and not -1
The problem is not in field name, it's in field type - bit.
It cant hold -1 value, only 0 and 1. And when SQL Server tries to change value to -1 it checks that -1 <> 0 and sets 1 (true). See documentation.
So convert the field before checking:
SELECT
C.CustomerID,
C.Name,
O.OrderID,
ISNULL(O.[OrderID],-1),
O.[Primary],
ISNULL(CONVERT(int,O.[Primary]),-1) as Weird
FROM Customer C
LEFT JOIN OrderTaken O
ON C.CustomerID = O.CustomerID
Or change column type to int or tinyint.

Update Statement Incorrectly Applying

I am trying to update 45000 rows with missing values on SQL Server 2000 sp4 Database.
I will try to simulate the table setup and conditions of values below:
I have two tables. One is holding valid transactions and the other has missing values in certain rows.
--Table #Trans holds valid transactions
Create Table #trans (
[DocumentNumber] [char](21) NOT NULL,
[CustomerName] [char](21) NOT NULL,
[CustomerID] [char](31) NOT NULL,
[ACTINDX] [int] NOT NULL,
[CRDTAMNT] [numeric](19, 5) NOT NULL,
[DEBITAMT] [numeric](19, 5) NOT NULL,
[TRXSORCE] [char](30) NOT NULL,
[TRXDATE] [datetime] NOT NULL
)
INSERT INTO #trans ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[TRXSORCE],[TRXDATE])
Values('INV20123','Andrew Sesinyi','A0001',2501,25620.00,0.000,'SALESTRN15012015','15-Jan-2015')
INSERT INTO #trans ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[TRXSORCE],[TRXDATE])
Values('INV20123','Andrew Sesinyi','A0001',2201,0.000,25620.00,'SALESTRN15012015','15-Jan-2015')
INSERT INTO #trans ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[TRXSORCE],[TRXDATE])
Values('PMTRN00155','Bame Moonwa','B0001',1700,1550.00,0.0000,'PYMNTTRN17012015','17-Jan-2015')
INSERT INTO #trans ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[TRXSORCE],[TRXDATE])
Values('PMTRN00155','Bame Moonwa','B0001',1900,0.0000,1550.00,'PYMNTTRN17012015','17-Jan-2015')
INSERT INTO #trans ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[TRXSORCE],[TRXDATE])
Values('PMTRN00156','OLERATO PHAMA','OL0001',1900,0.0000,1020.00,'PYMNTTRN17012015','17-Jan-2015')
INSERT INTO #trans ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[TRXSORCE],[TRXDATE])
Values('PMTRN00156','OLERATO PHAMA','OL0001',1700,1020.00,0.0000,'PYMNTTRN17012015','17-Jan-2015')
INSERT INTO #trans ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[TRXSORCE],[TRXDATE])
Values('INV20124','Bame Moonwa','B0001',2501,18000.00,0.000,'SALESTRN15012015','15-Jan-2015')
INSERT INTO #trans ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[TRXSORCE],[TRXDATE])
Values('INV20124','Bame Moonwa','B0001',2201,0.000,18000.00,'SALESTRN15012015','15-Jan-2015')
--Tables #GL holds some of the transactions with missing values i.e --DocumentNumber,CustomerID A and CustomerName
Create Table #GL(
[DocumentNumber] [char](21) ,
[CustomerName] [char](21),
[CustomerID] [char](31),
[ACTINDX] [int] NOT NULL,
[CRDTAMNT] [numeric](19, 5) NOT NULL,
[DEBITAMT] [numeric](19, 5) NOT NULL,
[ORTRXSORCE] [char](30) NOT NULL,
[TRXDATE] [datetime] NOT NULL
)
INSERT INTO #GL ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[ORTRXSORCE],[TRXDATE])
Values('','Andrew Sesinyi','A0001',2501,25620.00,0.000,'SALESTRN15012015','15-Jan-2015')
INSERT INTO #GL ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[ORTRXSORCE],[TRXDATE])
Values('','Andrew Sesinyi','A0001',2201,0.000,25620.00,'SALESTRN15012015','15-Jan-2015')
INSERT INTO #GL ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[ORTRXSORCE],[TRXDATE])
Values('','Bame Moonwa','B0001',1700,1550.00,0.0000,'PYMNTTRN17012015','17-Jan-2015')
INSERT INTO #GL ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[ORTRXSORCE],[TRXDATE])
Values('','Bame Moonwa','B0001',1900,0.0000,1550.00,'PYMNTTRN17012015','17-Jan-2015')
INSERT INTO #GL ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[ORTRXSORCE],[TRXDATE])
Values('','','',1900,0.0000,1020.00,'PYMNTTRN17012015','17-Jan-2015')
INSERT INTO #GL ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[ORTRXSORCE],[TRXDATE])
Values('','','',1700,1020.00,0.0000,'PYMNTTRN17012015','17-Jan-2015')
INSERT INTO #GL ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[ORTRXSORCE],[TRXDATE])
Values('INV20124','','',2501,18000.00,0.000,'SALESTRN15012015','15-Jan-2015')
INSERT INTO #GL ([DocumentNumber],[CustomerName],[CustomerID],[ACTINDX],[CRDTAMNT],[DEBITAMT],[ORTRXSORCE],[TRXDATE])
Values('INV20124','','',2201,0.000,18000.00,'SALESTRN15012015','15-Jan-2015')
When I run the following update statement incorrect updates are rendered to the #GL Records. Is there an alternative method or better way to apply an update records in this scenario.
UPDATE #GL
SET DocumentNumber = TR.DocumentNumber
, CustomerName = TR.CustomerName
,CustomerID =TR.CustomerID
FROM #GL GL
INNER JOIN #trans TR ON GL.ORTRXSORCE = TR.TRXSORCE
WHERE GL.ACTINDX = TR.ACTINDX
AND GL.DEBITAMT = TR.DEBITAMT
OR GL.CRDTAMNT = TR.CRDTAMNT
AND GL.TRXDATE = TR.TRXDATE
N.B I am trying to use this method to update 45000 records that have missing values.
N.B Multiple transactions can be posted as a batch to the #GL hence the shared TRXSORCE
Many Thanks for your insight in advance.
I bet you mean
WHERE GL.ACTINDX = TR.ACTINDX
AND (GL.DEBITAMT = TR.DEBITAMT OR GL.CRDTAMNT = TR.CRDTAMNT)
AND GL.TRXDATE = TR.TRXDATE

Update timestamp column when Foreign table updates without Trigger

I'm trying to setup a Timestamp/Rowversion on a Parent table so that when the Child table updates, the Timestamp on the Parent table row changes.
I don't need to know about the row in the Child table, just that according to the parent this particular row has changed.
USE [Test]
GO
CREATE TABLE [dbo].[Clerk](
[ID] [int] NOT NULL,
[Name] [varchar](20) NOT NULL,
[lastUpdate] [timestamp] NOT NULL,
CONSTRAINT [PK_Clerk] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
CREATE TABLE [dbo].[ClerkAddress](
[ClerkID] [int] NOT NULL,
[Address] [varchar](40) NOT NULL,
CONSTRAINT [PK_ClerkAddress] PRIMARY KEY CLUSTERED
(
[ClerkID] ASC
)
ALTER TABLE [dbo].[ClerkAddress] WITH CHECK ADD CONSTRAINT [FK_ClerkAddress_Clerk] FOREIGN KEY([ClerkID])
REFERENCES [dbo].[Clerk] ([ID])
ON UPDATE CASCADE
insert into Clerk (ID, Name) values (1, 'Test1')
insert into Clerk (id, Name) values (2, 'Test2')
insert into ClerkAddress (ClerkID, Address) values (1, 'address1')
insert into ClerkAddress (ClerkID, Address) values (2, 'address2')
using the following code examples.
update ClerkAddress set Address = NEWID() where ClerkID = 2
--no change to Clerk when address changes
select * from Clerk
select * from ClerkAddress
--Of course these update the lastUpdate in clerk
update Clerk set Name = 'test2' where ID = 2
update Clerk set Name = name
Is this even possible or do I need to make triggers for the updates? (update clerk set name = name where id = ClerkID)
You can make it appear as though the parent row is updated with a view.
You need to add a rowversion column to ClerkAddress, then
CREATE VIEW dbo.Clerk2
WITH SCHEMABINDING -- works for me on SQL Server 2012
AS
SELECT
C.ID, C.Name, ISNULL(MAX(CA.lastUpdate), C.lastUpdate) AS lastupdate
FROM
[dbo].[Clerk] C
LEFT JOIN
[dbo].[ClerkAddress] CA ON C.ID = CA.ClerkID
GROUP BY
C.ID, C.Name, C.lastUpdate
GO
SELECT * FROM dbo.Clerk2;
GO
update ClerkAddress set Address = NEWID() where ClerkID = 2;
GO
SELECT * FROM dbo.Clerk2;
GO
update ClerkAddress set Address = NEWID() where ClerkID = 2;
GO
SELECT * FROM dbo.Clerk2;
GO
This uses the highest value from rowversion yet preserves the actual rowversion on Clerk (which can still be used for optimistic concurrency by the client)
This works because rowversion is database unique

Resources