Showing posts with label constraints. Show all posts
Showing posts with label constraints. Show all posts

Wednesday, March 21, 2012

Is this correct use of INSTEAD OF Triggers?

I am loading data from table A into table B. Certain columns in B have
check constraints. I'd like for any rows from A, which violate
constraints, to be inserted into a third table, C. When the process is
finished, I'll have only good rows in B, and exeption rows in C.

I am investigating INSTEAD OF triggers, however my question to the
group is, is there a better or best practice for this scenario? This
must be common. Any high-level tips or direction will be highly
appreciated.

DAP>> loading data from table A into table B. Certain columns in B have
check constraints. I'd like for any rows from A, which violate
constraints, to be inserted into a third table, C. <<

You might want to use a cursor that attempts to insert each A row into
B and throws the exceptions into C. This would give you better control
and perhaps a chance to fix the bad rows with (ugh!) procedural code.

A moire set-oriented approach woudl be to create a VIEW on A whch has
the B constraints:

CREATE VIEW GoodA
AS SELECT *
FROM A
WHERE << B's constraints as predicates>> ;

You are probably thinking that the next step is to use:

CREATE VIEW BadA
AS SELECT *
FROM A
WHERE NOT (<< B's constraints as predicates>>);

But this does not work. A CHECK() constraint will accept an UNKNOWN
result from its predicate; a WHERE clause will reject them. You will
have to write a little extra code in each predicate to handle NULLs.

example:

CREATE TABLE B
( ..
foo INTEGER CHECK ( foo >= 0), -- works for null
..);

SELECT *
FROM A
WHERE ( foo >= 0 OR foo IS NULL);|||Hi

You can try something like:

INSERT INTO Table C
SELECT col1, col2, col3 FROM TABLE A
WHERE <CLAUSE TO TEST CONSTRAINT FAIL
INSERT INTO Table B
SELECT col1, col2, col3 FROM TABLE A
WHERE <CLAUSE TO TEST CONSTRAINTS PASS
OR
INSERT INTO Table B
SELECT col1, col2, col3 FROM TABLE A
WHERE NOT EXISTS ( SELECT * FROM TABLE C WHERE <CLAUSE TO CHECK NOT IN C>)

John

"Dan" <dpratte@.dpratte.com> wrote in message
news:1115474335.494377.167790@.o13g2000cwo.googlegr oups.com...
>I am loading data from table A into table B. Certain columns in B have
> check constraints. I'd like for any rows from A, which violate
> constraints, to be inserted into a third table, C. When the process is
> finished, I'll have only good rows in B, and exeption rows in C.
> I am investigating INSTEAD OF triggers, however my question to the
> group is, is there a better or best practice for this scenario? This
> must be common. Any high-level tips or direction will be highly
> appreciated.
> DAP|||Dan (dpratte@.dpratte.com) writes:
> I am loading data from table A into table B. Certain columns in B have
> check constraints. I'd like for any rows from A, which violate
> constraints, to be inserted into a third table, C. When the process is
> finished, I'll have only good rows in B, and exeption rows in C.
> I am investigating INSTEAD OF triggers, however my question to the
> group is, is there a better or best practice for this scenario? This
> must be common.

Not really.

I think the only way to do this without duplicating the constraints is
run a cursor one-by-one as suggested by Celko. An improvement could be
to first attempt to insert all, and if there is an error, use the
cursor as a fallback. But you could not do this in an INSTEAD OF
trigger, because an error in a trigger aborts the batch. You see,
the whole idea is that the INSERT statement should be atomic, either
all rows make it, or others not.

An alternative would be move the constraints to the trigger and check
for them there. An INSTEAD OF trigger would then redo the original
INSERT statement for the good rows. An AFTER trigger would delete
the bad rows.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||Hi

I missed the title to this! Rather than use a trigger I would put the logic
into a stored procedure.

John

"John Bell" <jbellnewsposts@.hotmail.com> wrote in message
news:427d0150$0$1878$da0feed9@.news.zen.co.uk...
> Hi
> You can try something like:
> INSERT INTO Table C
> SELECT col1, col2, col3 FROM TABLE A
> WHERE <CLAUSE TO TEST CONSTRAINT FAIL>
> INSERT INTO Table B
> SELECT col1, col2, col3 FROM TABLE A
> WHERE <CLAUSE TO TEST CONSTRAINTS PASS>
> OR
> INSERT INTO Table B
> SELECT col1, col2, col3 FROM TABLE A
> WHERE NOT EXISTS ( SELECT * FROM TABLE C WHERE <CLAUSE TO CHECK NOT IN C>)
> John
> "Dan" <dpratte@.dpratte.com> wrote in message
> news:1115474335.494377.167790@.o13g2000cwo.googlegr oups.com...
>>I am loading data from table A into table B. Certain columns in B have
>> check constraints. I'd like for any rows from A, which violate
>> constraints, to be inserted into a third table, C. When the process is
>> finished, I'll have only good rows in B, and exeption rows in C.
>>
>> I am investigating INSTEAD OF triggers, however my question to the
>> group is, is there a better or best practice for this scenario? This
>> must be common. Any high-level tips or direction will be highly
>> appreciated.
>>
>> DAP
>>

Wednesday, March 7, 2012

Is there any way to disable/enable all constraints in a database ?

Is there any way to disable/enable all constraints in a database ?To Disable
sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
go
sp_msforeachtable "ALTER TABLE ? DISABLE TRIGGER all"
go
To Re-enable
sp_msforeachtable"ALTER TABLE ? CHECK CONSTRAINT all"
go
sp_msforeachtable "ALTER TABLE ? ENABLE TRIGGER all"
go
"Vlad Gonchar" <VladG@.Frogware.com> wrote in message
news:uCjyRYwlDHA.3024@.tk2msftngp13.phx.gbl...
>
>|||Note though that this does no affect Primary Key, Unique or Default constraints.
--
Tibor Karaszi, SQL Server MVP
Archive at: http://groups.google.com/groups?oi=djq&as ugroup=microsoft.public.sqlserver
"Mike" <Mike@.Comcast.net> wrote in message news:ek03%23fwlDHA.3320@.tk2msftngp13.phx.gbl...
> To Disable
> sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
> go
> sp_msforeachtable "ALTER TABLE ? DISABLE TRIGGER all"
> go
> To Re-enable
> sp_msforeachtable"ALTER TABLE ? CHECK CONSTRAINT all"
> go
> sp_msforeachtable "ALTER TABLE ? ENABLE TRIGGER all"
> go
>
> "Vlad Gonchar" <VladG@.Frogware.com> wrote in message
> news:uCjyRYwlDHA.3024@.tk2msftngp13.phx.gbl...
> >
> >
> >
>|||In my book online there is no "sp_msforeachtable" stored procedure.
Issuing SELECT @.@.VERSION gives the following:
Microsoft SQL Server 2000 - 8.00.194 (Intel X86) Aug 6 2000 00:57:48
Copyright (c) 1988-2000 Microsoft Corporation Enterprise Edition on Windows
NT 4.0 (Build 1381: Service Pack 6)
"Mike" <Mike@.Comcast.net> wrote in message
news:ek03#fwlDHA.3320@.tk2msftngp13.phx.gbl...
> To Disable
> sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
> go
> sp_msforeachtable "ALTER TABLE ? DISABLE TRIGGER all"
> go
> To Re-enable
> sp_msforeachtable"ALTER TABLE ? CHECK CONSTRAINT all"
> go
> sp_msforeachtable "ALTER TABLE ? ENABLE TRIGGER all"
> go
>
> "Vlad Gonchar" <VladG@.Frogware.com> wrote in message
> news:uCjyRYwlDHA.3024@.tk2msftngp13.phx.gbl...
> >
> >
> >
>|||sp_msforeachtable is an "undocumented" system stored procedure so you won't
find it in BOL.
On a seperate note make sure you are protected from Slammer
http://www.microsoft.com/sql/techinfo/administration/2000/security/slammer.asp
http://www.microsoft.com/sql/downloads/2000/sp3.asp
--
HTH
Jasper Smith (SQL Server MVP)
I support PASS - the definitive, global
community for SQL Server professionals -
http://www.sqlpass.org
"Vlad Gonchar" <VladG@.Frogware.com> wrote in message
news:%23qtnD0wlDHA.360@.TK2MSFTNGP12.phx.gbl...
In my book online there is no "sp_msforeachtable" stored procedure.
Issuing SELECT @.@.VERSION gives the following:
Microsoft SQL Server 2000 - 8.00.194 (Intel X86) Aug 6 2000 00:57:48
Copyright (c) 1988-2000 Microsoft Corporation Enterprise Edition on Windows
NT 4.0 (Build 1381: Service Pack 6)
"Mike" <Mike@.Comcast.net> wrote in message
news:ek03#fwlDHA.3320@.tk2msftngp13.phx.gbl...
> To Disable
> sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
> go
> sp_msforeachtable "ALTER TABLE ? DISABLE TRIGGER all"
> go
> To Re-enable
> sp_msforeachtable"ALTER TABLE ? CHECK CONSTRAINT all"
> go
> sp_msforeachtable "ALTER TABLE ? ENABLE TRIGGER all"
> go
>
> "Vlad Gonchar" <VladG@.Frogware.com> wrote in message
> news:uCjyRYwlDHA.3024@.tk2msftngp13.phx.gbl...
> >
> >
> >
>|||You can find it in master database.