Showing posts with label developing. Show all posts
Showing posts with label developing. Show all posts

Monday, March 26, 2012

Insert with multiple tables

Hi All SQLStars

I am kind of new to developing complex databases in SQL Server 2005, so I hope there is someone out there with the answer to all my prayers.

I have 3 distinct tables

tblContainer

ContNum smallint (primary key)

Length smallint

Stop smallint

ContTypeID tinyint

HookUpID tinyint

tblContTypes

ContTypeID tinyint

ContType nvarchar(30)

tblHookUp

HookUpID tinyint

HookUp nvarchar(30)

I need to make an Insert query (and an update query) as stored procedures that can insert/update rows in the tblContainer, but I want the user not to enter ContTypeID or HookUpID but rather ContType and HookUp. Further there are some conditions to be validated:

WHEN ContNum BETWEEN 100 AND 199 THEN HookUpID ='13'

WHEN ContNum BETWEEN 1000 AND 1999 THEN HookUpID ='1'

WHEN ContNum BETWEEN 2000 AND 2499 THEN HookUpID ='2'

WHEN ContNum BETWEEN 2500 AND 2999 THEN HookUpID ='3'

WHEN ContNum BETWEEN 3000 AND 3249 THEN HookUpID ='4'

WHEN ContNum BETWEEN 3250 AND 3499 THEN HookUpID ='5'

WHEN ContNum BETWEEN 3500 AND 3749 THEN HookUpID ='6'

WHEN ContNum BETWEEN 3750 AND 3999 THEN HookUpID ='7'

WHEN ContNum BETWEEN 4000 AND 4249 THEN HookUpID ='8'

WHEN ContNum BETWEEN 4250 AND 4449 THEN HookUpID ='9'

WHEN ContNum BETWEEN 4500 AND 4749 THEN HookUpID ='10'

WHEN ContNum BETWEEN 4750 AND 4999 THEN HookUpID ='11'

WHEN ContNum BETWEEN 5000 AND 5249 THEN HookUpID ='12'

ContNum can only be a number in the above used intervals, there's a constraint on tblContainer to ensure that.

I've tried this code, but obviously it doesn't work, can you tell me why?

CREATE PROCEDURE usp_InsertContainer

(

@.ContNum smallint,

@.Length smallint,

@.Stop smallint,

@.ContType nvarchar(30),

@.HookUp nvarchar(30)

)

INSERT INTO tblContainer (ContNum, Length, Stop, ContTypeID, HookUpID)

WHEN ContNum BETWEEN 100 AND 199 THEN HookUpID ='13'

WHEN ContNum BETWEEN 1000 AND 1999 THEN HookUpID ='1'

WHEN ContNum BETWEEN 2000 AND 2499 THEN HookUpID ='2'

WHEN ContNum BETWEEN 2500 AND 2999 THEN HookUpID ='3'

WHEN ContNum BETWEEN 3000 AND 3249 THEN HookUpID ='4'

WHEN ContNum BETWEEN 3250 AND 3499 THEN HookUpID ='5'

WHEN ContNum BETWEEN 3500 AND 3749 THEN HookUpID ='6'

WHEN ContNum BETWEEN 3750 AND 3999 THEN HookUpID ='7'

WHEN ContNum BETWEEN 4000 AND 4249 THEN HookUpID ='8'

WHEN ContNum BETWEEN 4250 AND 4449 THEN HookUpID ='9'

WHEN ContNum BETWEEN 4500 AND 4749 THEN HookUpID ='10'

WHEN ContNum BETWEEN 4750 AND 4999 THEN HookUpID ='11'

WHEN ContNum BETWEEN 5000 AND 5249 THEN HookUpID ='12'

INNER JOIN tblHookUp on tblContainer.HookUpID=tblHookUp.HookUpID

VALUES(@.ContNum, @.Length, @.Stop, @.HookUp)

The result should look like this:

ContNum, Length, Stop, ContType, HookUp

1, 100, 15, Very Large, Wire

I'd really appriciate your help in this riddle - thanks a bundle.

Kind regards

Tina Nielsen

Denmark

Hi Tina,

Use a "select" statement as the source for the "insert" one.

INSERT INTO dbo.tblContainer (ContNum, Length, Stop, ContTypeID, HookUpID)

select

@.ContNum,

@.Length,

@.Stop,

(select ContTypeID from dbo.tblContTypes where ContType = @.ContType),

case

WHEN @.ContNum BETWEEN 100 AND 199 THEN HookUpID ='13'

WHEN @.ContNum BETWEEN 1000 AND 1999 THEN HookUpID ='1'

WHEN @.ContNum BETWEEN 2000 AND 2499 THEN HookUpID ='2'

WHEN @.ContNum BETWEEN 2500 AND 2999 THEN HookUpID ='3'

WHEN @.ContNum BETWEEN 3000 AND 3249 THEN HookUpID ='4'

WHEN @.ContNum BETWEEN 3250 AND 3499 THEN HookUpID ='5'

WHEN @.ContNum BETWEEN 3500 AND 3749 THEN HookUpID ='6'

WHEN @.ContNum BETWEEN 3750 AND 3999 THEN HookUpID ='7'

WHEN @.ContNum BETWEEN 4000 AND 4249 THEN HookUpID ='8'

WHEN @.ContNum BETWEEN 4250 AND 4449 THEN HookUpID ='9'

WHEN @.ContNum BETWEEN 4500 AND 4749 THEN HookUpID ='10'

WHEN @.ContNum BETWEEN 4750 AND 4999 THEN HookUpID ='11'

WHEN @.ContNum BETWEEN 5000 AND 5249 THEN HookUpID ='12'

else null

end

What about adding columns [ContNum_From] and [ContNum_To] to table [tblHookUp], and using:

INSERT INTO dbo.tblContainer (ContNum, Length, Stop, ContTypeID, HookUpID)

select

@.ContNum,

@.Length,

@.Stop,

(select ContTypeID from dbo.tblContTypes where ContType = @.ContType),

(select HookUpID from dbo.tblHookUp where @.ContNum between [ContNum_From] and [ContNum_To])

AMB

|||

Hi AMB

Thank you very, very much for your rapid reply. I'm quite sure this will solve my problem.

Just to clarify, can I use this as a template for an update and delete query as well?

Again thank very much for helping me out.

Kind regards

Tina Nielsen

Denmark

|||

Hi, Tina!

Another option is to use computed column instead of storing data in Database:

Code Snippet

CREATETABLE tblContainer (

ContNum smallintPRIMARYKEY,

Length smallint,

Stop smallint,

ContTypeID tinyint,

HookUpID AS(CASE

WHEN ContNum BETWEEN 100 AND 199 THEN 13

WHEN ContNum BETWEEN 1000 AND 1999 THEN 1

WHEN ContNum BETWEEN 2000 AND 2499 THEN 2

WHEN ContNum BETWEEN 2500 AND 2999 THEN 3

WHEN ContNum BETWEEN 3000 AND 3249 THEN 4

WHEN ContNum BETWEEN 3250 AND 3499 THEN 5

WHEN ContNum BETWEEN 3500 AND 3749 THEN 6

WHEN ContNum BETWEEN 3750 AND 3999 THEN 7

WHEN ContNum BETWEEN 4000 AND 4249 THEN 8

WHEN ContNum BETWEEN 4250 AND 4449 THEN 9

WHEN ContNum BETWEEN 4500 AND 4749 THEN 10

WHEN ContNum BETWEEN 4750 AND 4999 THEN 11

WHEN ContNum BETWEEN 5000 AND 5249 THEN 12

END)

)

So, whenever you insert or update [ContNum] column, in SELECT queries value of HookUpID is calculated automatically. You don't need to store it in database and use additional tricks during update operation.

NOTE, that this option is applicable only if SELECT statement execution speed is not critical! As I know, computed columns affect SELECT statement performance. Although, in this case, when rows count in the table is not much, it's not significant.

|||

Hi Tina,

For a "delete" you just need the PK to be deleted, and for "update", well it depends if you will be updating the PK also.

declare @.ContNum

set @.ContNum = 10

delete from

where ContNum = @.ContNum

go

declare @.ContNum int, @.Length int, @.Stop int

set @.ContNum = 10

set @.Length = 20

set @.Stop = 30

update

dbo.tblContainer

set

Length = @.Length,

Stop = @.Stop

where

ContNum = @.ContNum

go

AMB

Monday, March 19, 2012

insert then update...

greetings
I am developing an application for the marketing dept at my company.Basically users can build the content of an email to be sent to oursubscriber database.
I am wanting the application to initailly save the content into a database, the update the most recently inserted row.
The save button uses the following SQL command:
Dim SqlMethod As String ="INSERT INTO CZC_email (Offer, SendDate, Destinations, Copy, BannerURL)VALUES ('" & txtCampaignName.Text & "','" &calCampaignDate.SelectedDate.ToString("yy/dd/MM") & "','" &DestinationsSelected & "','" & FreeTextBox2.Text & "', '"& txtBannerPath.Text & "')SELECT @.@.IDENTITY AS 'CZ_ID'"
And my update button has this SQL command:
Dim SqlMethod As String ="UPDATE CZC_email SET SendDate = '" &calCampaignDate.SelectedDate.ToString("yy/dd/MM") & "', Offer = '"& txtCampaignName.Text & "',Destinations = '" &DestinationsSelected & "', BannerURL = '" & txtBannerPath.Text& "' WHERE CZ_ID = @.@.IDENTITY "
but it doesnt seem to be updating. anyone know what I'm doing wrong?
Cheers

(1) Use a stored proc.
(2) Use SCOPE_IDENTITY() instead of @.@.IDENTIY. Check books on line for the differences.
(3) Use Parameterized Queries to prevent SQL Injection atatcks (google for more info on this).|||Save the @.@.IDENTITY values you get from insert command & then in the update command pass the value returned from the insertion instead of @.@.IDENTITY|||I've tried saving the @.@.identity and scope_identity as a value ofvariable varCZ_ID by using the following code (i'm using the MS DAAB)
varCZ_ID = dataReader("SCOPE_IDENTITY")
or

varCZ_ID = dataReader("CZ_ID")

however, this is erroring 'Invalid attempt to read when no data is present.'
Any ideas what I'm doing wrong? this is really doing my head in!
Thanks
|||If you use a stored proc you could save a trip to the server and get back accurate Id.
|||yes I agree, I just wanted to get it working first off.
I managed to fix the problem by saving the @.@.IDENTITY into a session variable.

|||@.@.IDENTITY does not always give you the identity value that just gotgenerated by the insert statement. If multiple calls were made at thesame time it could mix up the Id's. So it is advised to useSCOPE_DENTITY() instead of @.@.IDENTITY.
|||Thats a good point, and something I am aware off.
For this particular application is not a big deal, as it only going to be used by two people - and not at the sametime.
However i will look to improve it soon, and that will be things I will do.
Cheers