[dba-SQLServer] tsql help - propogate that pk

Shamil Salakhetdinov shamil at users.mns.ru
Thu Jul 15 17:32:23 CDT 2004


Hi Billy,

You didn't ask about inserting several rows using instead of insert
trigger, did you? :)

Well, I think it can be done without cursors but we have to assume that
there is no UNIVERSAL solution for such a case - I mean that for each
certain case the cursor-less solution with instead of triggers could
have quite different implementation - as always in programming an
"optimal" solution is a balance of interests, a compromise:

So if we assume that when several rows are inserted against my sample
view then this means that:

1. they all belong to one order
2. product name is unique

Then one of the the solutons is:

- insert all rows into tblProduct from inserted if there is no yet such
product,
- insert one row into tblOrder from inserted,
- insert all rows into tblOrdItem from inserted joined to tblProduct on
ProdName

See SQL script in P.S. of this message.

If you need something more complicated - e.g. inserting several orders
against view like in the current sample avoiding cursors' usage by all
means - if you need that - then you're welcome to hire me to do that and
other tricky work! :)

HTH,
Shamil

P.S. Solution:


CREATE TRIGGER [qselInsert] ON [dbo].[qselOrder]
INSTEAD OF INSERT
AS
declare @ordID int

Set NoCount On

-- /////////////////////////////////////////////////
Insert Into [dbo].[tblProduct]
(
   [prodName]
 , [prodCurPrice]
)
select
   prodName
 , prodCurPrice
from inserted where (prodName not in (select prodName from tblProduct))

-- /////////////////////////////////////////////////
Insert Into [dbo].[tblOrder]
(
   [ordDate]
 , [custId]
 , [ordCurTotal]
)
select top 1
   ordDate
 , custId
 , ordCurTotal
from inserted

Set @ordID = Cast(SCOPE_IDENTITY() As [int])
-- /////////////////////////////////////////////////
Insert Into [dbo].[tblOrderItem]
(
   [ordId]
 , [prodId]
 , [oitAmount]
)
select
   @ordId
 , p.prodId
 , oitAmount
from inserted i inner join tblProduct p on i.prodName = p.prodName
-- /////////////////////////////////////////////////

Set NoCount Off
----- Original Message ----- 
From: "Billy Pang" <tuxedo_man at hotmail.com>
To: <dba-sqlserver at databaseadvisors.com>
Sent: Friday, July 16, 2004 1:18 AM
Subject: Re: [dba-SQLServer] tsql help - propogate that pk


> Hi Shamil:
>
> Thanks for your assistance.  Your solution will only work based on the
> assumption that records can only be inserted into tblOrder one at a
time; if
> insert statement for tblOrder table has "select" as source, then the
> tblorderid fk in tblorderitem table may contain incorrect value.
>
> Using below example as example, execute the following insert
statements:
>
> <--- cut here --->
> insert into qselOrder(ordDate, custId, ordCurTotal, prodName,
prodCurPrice,
> oitAmount)
> values(getdate(),1,2,'product name',4,5)
>
> insert into qselOrder(ordDate, custId, ordCurTotal, prodName,
prodCurPrice,
> oitAmount)
> select ordDate, custId, ordCurTotal, prodName, prodCurPrice, oitAmount
from
> qselOrder
>
> insert into qselOrder(ordDate, custId, ordCurTotal, prodName,
prodCurPrice,
> oitAmount)
> select ordDate, custId, ordCurTotal, prodName, prodCurPrice, oitAmount
from
> qselOrder
> <--- cut here --->
>
> assuming tblorder table is empty from very beginning, it will insert
four
> records into tblorder table as expected and four records into
tblorderitems
> table as expected.  however, the fourth record in tblorder table does
not
> have any related records in tblorderitems.
>
> One way around this problem is to load the values within the
"inserted"
> pseudo table into a table variable (assuming ss2k) or temporary table
and
> loop through them using database cursor.  However, I am wondering if
there
> is another way.
>
> sincerely,
> Billy
>




More information about the dba-SQLServer mailing list