Showing posts with label fails. Show all posts
Showing posts with label fails. Show all posts

Wednesday, March 21, 2012

INSERT TRIGGER - For you Guru's.

Why is it that this trigger fails to pick up the duplicate on an Insert from Select Statement?

INSTEAD OF INSERT
AS

BEGIN
SET NOCOUNT ON
-- CHECK FOR DUPLICATE PERSON
IF NOT EXISTS (SELECT HOMEPHONE
FROM
CBIZ_CONSULTANTS N,
INSERTED I
WHERE
N.HOMEPHONE = I.HOMEPHONE
)

INSERT INTO [dbo].[CBIZ_Consultants] (HOMEPHONE)
SELECT (HOMEPHONE)
FROM INSERTED

ELSE
PRINT 'SEND TO DUPLICATE TABLE'

END


FOR EXAMPLE IF I HAVE THE FOLLOWING RECORDS.

RECORDID PERSON HOMPHONE
1 JONN 415-555-1212
2 JON 415-555-1212

IF I DO AN INSERT MULTPLE TIMES
WHERE RECORDID = 1 IT WILL PRINT 'SEND TO DUPLICATE TABLE'

HOWEVER...

IF I DO AN INSERT INTO CBIZ_CONSULTANTS (RECORDID, PERSON, HOMEPHONE)
SELECT RECORDID, PERSON, HOMEPHONE FROM PERSON WHERE PERSON LIKE 'JON%'

THIS IS INSERT BOTH RECORDS INTO THE TABLE AND NOT PICK UP THE DUPLICATE?

David:

The way I understand you, at the beginning of the insert you have an empty CBIZ_CONSULTANTS table with the two records listed in the PERSON table. You attempt to insert these two records from the PERSON table into the CBIZ_CONSULTANTS table and you want your trigger to block the insert because the two records have the same HOMEPHONE entry.

In this case both records will be inserted because at trigger execution time the INSERTED pseudo table contains both entries and the CBIZ_Consultants table doesn't contain any entries. Under these conditions the IF part activates instead of the ELSE condition because there are NO records in the CBIZ_CONSULTANTS table; therefore, the NOT EXISTS statement is true. Remember: This trigger does not fire once for each row inserted; it fires once and loads both records inserted into the INSERTED pseudo table. This is a common misunderstanding related to triggers. Many triggers get incorrectly written such that they work with single record situations and fail to handle multiple records properly.

Suppose your first JON record is written to the CBIZ_CONSULTANTS table. Now you attempt to insert these two records:
(2, JON, 415-555-1212) and (3, JIM 416-555-1212). Now when your triggers fires you will get the 'SEND TO DUPLICATE TABLE' message and the (3, JIM 416-555-1212) record will NOT get inserted. (MAN this keyboard is the pits)

What would be more appropriate to hand the insert is something like:

INSERT INTO dbo.CBIZ_consultants (homephone)
SELECT homephone
FROM INSERTED i
WHERE NOT EXISTS
( SELECT 0 FROM CBIZ_consultants c
WHERE i.homephone = c.homephone
)

This will work properly for both single record and multi-record inserts.


Dave

|||Dave,

thank you very much for the reply I couldn't figure out why it was treating multi inserts different from single inserts. Very helpful!

I am left in somewhat of a jam with the above solution since I need to perform conditional logic based on NOT EXISTS.

I guess I could delete the rows from my source table that EXISTS in cbiz_consultants after the above query and treat that like my duplicate table...

Do you know if there are any other solutions than this?|||

David:

Much of the answer to your question lies in the data and what you want to do with it. If ultimately what you want to do is (1) update records with pre-existing matches and (2) insert records that have no pre-existing matches then you can put an

UPDATE
WHERE EXISTS

at the beginning of the trigger and follow it with an

INSERT
WHERE NOT EXISTS

However, this only works if the INSERTED pseudo table contains no records with the same key. In the example you cited an insert attempts to insert two records with the same home phone number. This requires a little more work. You now probably need to sequence your records and (1) insert the first record of the sequence and (2) update with the last record of the sequence. Also, does your table include a primary key?

Try doing a search here for INSTEAD OF TRIGGER; you should be able to get some better information that what I have shown. In a couple of the ones I just looked at Louis Davidson has some really good examples. These previous posts should be helpful.


Dave

|||Following Dave's suggestion, you could have a second insert into the duplicates table using [EXISTS] instead of [NOT EXISTS].

Monday, March 12, 2012

Insert statement for datetime column fails

I ve a simple table with a column of type datetime. I ve successfully inserted the following values in it,

2006-09-13 18:00:10
2006-09-14 18:00:10
2006-09-15 18:00:10

however, it fails when i try to insert the value 0000-00-00 00:00:00. ie., the following insert statement fails

INSERT INTO TEST VALUES('0000-00-00 00:00:00')

The error thrown is,

Server Msg 242, Level 16, State 3, Line 1
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value. The statement has been terminated.Obviously SQL Server thinks that '0000-00-00 00:00:00' is not a valid date and I couldn't agree more.
You should use NULL to "mark" a column's value as absent, not some strange (invalid) value|||hi shammat,

thanks for the reply.. whats the least possible valid day i could enter for a datetime column..|||What's wrong with NULL?

Edit:

The lowest value is documented in the manual:
http://msdn2.microsoft.com/en-us/library/ms187819.aspx|||Hi shammat,

I ve migrated an existing table structure and its data from MySQL to SQLServer, in MySQL the column is Not NULL and one of the row has the value 0000-00-00 00:00:00. When i tried to create the same in SQLServer i faced such errors..|||This is something I have seen a lot recently.
Why would anybody declare a column as NOT NULL and then put a totally meaningless value in there, just to comply with the NOT NULL constraint.

That sure does not make any sense to me

I do understand that this was not your decision, I'm just wondering why people do such stupid things|||shammat, very nicely stated, i totally agree

the fact that mysql allows a "zero date" sure detracts from its reputation

the fact that mysql programmers would actually utilize it detracts from them even more|||To be fair against the MySQL users:
I have seen this in an Oracle environment as well, they simply used 1970-01-01 instead...

But then - I have seen it only once with Oracle, whereas I tend to see it more often in the MySQL area|||I've always been in favor of using a NULL when possible to mark data with an unknown or an unknowable value, but many systems can't cope with that due to the programming language being used... Many COBOL variants just don't cope with NULL very gracefully, and a number of "4GL" wannabes have the same problems, although they are dressed up in newer clothes.

In defense of the SQL Server choice for minimum date, that wasn't truly their choice... They had to deal with calendar reformations, and simply picked the earliest date that wasn't likely to have problems for most users. The Julian to Gregorian conversion was messy, it wasn't implemented the same way in many places, and wasn't implemented at the same time everywhere... We take it for granted that only timezones need to be considered to determine when 2006-11-01 will occur because the world has only had a couple of calendars since 1800, and all of those calendars conveniently convert to the Gregorian. This has not been the case throughout history.

-PatP|||And a number of "4GL" wannabes have the same problems, although they are dressed up in newer clothes.Understable, but still not nice :)

In defense of the SQL Server choice for minimum date, that wasn't truly their choice...I find the minimum date to be perfectly fine, as a matter of fact a lot better than allowing 0000-00-00.|||the minimum date is not "perfectly fine"

it may be practicable, but it does introduce another form of "three-valued logic"

for instance, if you assign the minimum date to a date_of_birth column in those instances when you do not know the person's date_of_birth, you cannot simply go blithely ahead and calculate the person's current age

well, technically speaking, you could, but it would be wrong

so using the minimum date is far from "perfect"|||the minimum date is not "perfectly fine"
I didn't mean that the usage of it was fine. I totally agree with you that it is nonsens to use special values for this purpose

I meant the restriction for a minimum date value is acceptable. A valid date as the minimum date is "perfectly fine" compate to 0000-00-00|||I just wonder how much code relies of that date "not being there" as 0000-00-00....|||I just wonder how much code relies of that date "not being there" as 0000-00-00....
exactly

and if you should ever need to move the app to another database platform? code changes!!

nothing more fun than coming in to the office on a sunny saturday afternoon to find all occurrences of 0000-00-00 and replace them with 1970-01-01

whereas if you had used NULL in the first place...

:)

Insert Statement Fails on Linked servers

Hi,
we have a local server with a database say A on it . we also have a
linked server which has a database B.
now we are trying to insert into a table in a using data from the
database B. both of the tables in both the database are the same in
structure .
now when i use a query like
insert into a.Table1
( No,
Name
)
select
no,
name
frrom
host_sever.B.dbo.table1
where <some condition >
the above query fails and the error says a nested distributed
transaction cannot be started
both the tables have a trigger attached to it .
we found that first inserting the data into a temp table and then
copying that data into the main table in local server in database A
works fine.
also i tested some scenario with no trigger and it works fine .
is this how it is when there are triggers attached and is there any way
we can succesfully run the query ableve without temp tables.
thanks
ravinderavravinder@.gmail.com wrote:
> Hi,
> we have a local server with a database say A on it . we also have a
> linked server which has a database B.
> now we are trying to insert into a table in a using data from the
> database B. both of the tables in both the database are the same in
> structure .
> now when i use a query like
> insert into a.Table1
> ( No,
> Name
> )
> select
> no,
> name
> frrom
> host_sever.B.dbo.table1
> where <some condition >
> the above query fails and the error says a nested distributed
> transaction cannot be started
> both the tables have a trigger attached to it .
> we found that first inserting the data into a temp table and then
> copying that data into the main table in local server in database A
> works fine.
> also i tested some scenario with no trigger and it works fine .
> is this how it is when there are triggers attached and is there any way
> we can succesfully run the query ableve without temp tables.
> thanks
> ravinder
>
Is the MSDTC service running on both machines? Is it enabled for
network access?
Tracy McKibben
MCDBA
http://www.realsqlguy.com|||Tracy McKibben wrote:
> avravinder@.gmail.com wrote:
> Is the MSDTC service running on both machines? Is it enabled for
> network access?
>
> --
> Tracy McKibben
> MCDBA
> http://www.realsqlguy.com
i looked at the services and DTC is runnign . there is another one is
control panel which says MSDTC which i think you are referreing too.
the network protocol says TCP/Ip and the salection default MS DTC
server is blank and disabled .
should this also not have created a issue when dum[ing into the temp
table and cause the same issue.
thanks
ravinder|||avravinder@.gmail.com wrote:
> Tracy McKibben wrote:
> i looked at the services and DTC is runnign . there is another one is
> control panel which says MSDTC which i think you are referreing too.
> the network protocol says TCP/Ip and the salection default MS DTC
> server is blank and disabled .
> should this also not have created a issue when dum[ing into the temp
> table and cause the same issue.
> thanks
> ravinder
>
No, it wouldn't cause an issue that way. Everything that occurs within
a trigger is done inside a transaction, and for a transaction to cross a
linked server, DTC must be available.
I would suggest starting here:
http://www.sqlservercentral.com/col...realsqlguy.com

Insert Statement Fails on Linked servers

Hi,
we have a local server with a database say A on it . we also have a
linked server which has a database B.
now we are trying to insert into a table in a using data from the
database B. both of the tables in both the database are the same in
structure .
now when i use a query like
insert into a.Table1
( No,
Name
)
select
no,
name
frrom
host_sever.B.dbo.table1
where <some condition >
the above query fails and the error says a nested distributed
transaction cannot be started
both the tables have a trigger attached to it .
we found that first inserting the data into a temp table and then
copying that data into the main table in local server in database A
works fine.
also i tested some scenario with no trigger and it works fine .
is this how it is when there are triggers attached and is there any way
we can succesfully run the query ableve without temp tables.
thanks
ravinderavravinder@.gmail.com wrote:
> Hi,
> we have a local server with a database say A on it . we also have a
> linked server which has a database B.
> now we are trying to insert into a table in a using data from the
> database B. both of the tables in both the database are the same in
> structure .
> now when i use a query like
> insert into a.Table1
> ( No,
> Name
> )
> select
> no,
> name
> frrom
> host_sever.B.dbo.table1
> where <some condition >
> the above query fails and the error says a nested distributed
> transaction cannot be started
> both the tables have a trigger attached to it .
> we found that first inserting the data into a temp table and then
> copying that data into the main table in local server in database A
> works fine.
> also i tested some scenario with no trigger and it works fine .
> is this how it is when there are triggers attached and is there any way
> we can succesfully run the query ableve without temp tables.
> thanks
> ravinder
>
Is the MSDTC service running on both machines? Is it enabled for
network access?
Tracy McKibben
MCDBA
http://www.realsqlguy.com|||Tracy McKibben wrote:
> avravinder@.gmail.com wrote:
> > Hi,
> > we have a local server with a database say A on it . we also have a
> > linked server which has a database B.
> > now we are trying to insert into a table in a using data from the
> > database B. both of the tables in both the database are the same in
> > structure .
> > now when i use a query like
> > insert into a.Table1
> > ( No,
> > Name
> > )
> > select
> > no,
> > name
> > frrom
> > host_sever.B.dbo.table1
> > where <some condition >
> >
> > the above query fails and the error says a nested distributed
> > transaction cannot be started
> > both the tables have a trigger attached to it .
> > we found that first inserting the data into a temp table and then
> > copying that data into the main table in local server in database A
> > works fine.
> > also i tested some scenario with no trigger and it works fine .
> >
> > is this how it is when there are triggers attached and is there any way
> > we can succesfully run the query ableve without temp tables.
> >
> > thanks
> > ravinder
> >
> Is the MSDTC service running on both machines? Is it enabled for
> network access?
>
> --
> Tracy McKibben
> MCDBA
> http://www.realsqlguy.com
i looked at the services and DTC is runnign . there is another one is
control panel which says MSDTC which i think you are referreing too.
the network protocol says TCP/Ip and the salection default MS DTC
server is blank and disabled .
should this also not have created a issue when dum[ing into the temp
table and cause the same issue.
thanks
ravinder|||avravinder@.gmail.com wrote:
> Tracy McKibben wrote:
>> avravinder@.gmail.com wrote:
>> Hi,
>> we have a local server with a database say A on it . we also have a
>> linked server which has a database B.
>> now we are trying to insert into a table in a using data from the
>> database B. both of the tables in both the database are the same in
>> structure .
>> now when i use a query like
>> insert into a.Table1
>> ( No,
>> Name
>> )
>> select
>> no,
>> name
>> frrom
>> host_sever.B.dbo.table1
>> where <some condition >
>> the above query fails and the error says a nested distributed
>> transaction cannot be started
>> both the tables have a trigger attached to it .
>> we found that first inserting the data into a temp table and then
>> copying that data into the main table in local server in database A
>> works fine.
>> also i tested some scenario with no trigger and it works fine .
>> is this how it is when there are triggers attached and is there any way
>> we can succesfully run the query ableve without temp tables.
>> thanks
>> ravinder
>> Is the MSDTC service running on both machines? Is it enabled for
>> network access?
>>
>> --
>> Tracy McKibben
>> MCDBA
>> http://www.realsqlguy.com
> i looked at the services and DTC is runnign . there is another one is
> control panel which says MSDTC which i think you are referreing too.
> the network protocol says TCP/Ip and the salection default MS DTC
> server is blank and disabled .
> should this also not have created a issue when dum[ing into the temp
> table and cause the same issue.
> thanks
> ravinder
>
No, it wouldn't cause an issue that way. Everything that occurs within
a trigger is done inside a transaction, and for a transaction to cross a
linked server, DTC must be available.
I would suggest starting here:
http://www.sqlservercentral.com/columnists/ckempster/debuggingmsdtcissues.asp
Tracy McKibben
MCDBA
http://www.realsqlguy.com

Insert Statement Fails

All,

Trying to format some data before I drop it into a grid. I have this in a stored proc but it fails


CREATE TABLE dbo.tmpSummary (
AE NVARCHAR(50)
, PRODUCT_LINE NVARCHAR(20)
, ANNUAL_REV NUMERIC (9)
, [GRWTH/ACQ] NUMERIC (9)
, RETENTION NUMERIC (9)
, CATEGORY NVARCHAR(20)

)

INSERT INTO dbo.tmpSummary (
[AE]
, [PRODUCT_LINE]
, [ANNUAL_REV]
, [GRWTH/ACQ]
, RETENTION
, CATEGORY
)
SELECT
A.AE
, A.PRODUCT_LINE
, A.ANNUAL_REV
, A.[GRWTH/ACQ]
, A.RETENTION
, B.PRODUCT_CATEGORY AS CATEGORY

FROM
tmpSummary A RIGHT OUTER JOIN PRODUCT B
On A.PRODUCT_LINE=B.PRODUCT_CATEGORY

I keep getting an error "Invalid Column name CATEGORY" Anyone know why? Thanks

Never mind. Maybe if I learn to read i could see that i am trying to insert data BACK into the same table. It should have been something else.

|||

Only reason why you would get that error is that you don't have a column in your table named CATEGORY. Check your table defenition again to make sure you have the spelling of the column name correct. I know that gets me alotStick out tongue

Wednesday, March 7, 2012

insert query fails (if form fields left empty)

Dear All,

I have created a table in my SQL server database, the problem i am facing is my insert query fails if i leave any form field empty (leave it blank). On my back-end table, only one field is mandatory, and others have been set with the constraint "allow null".

As per our business requirement, except one value is complusory while others are optional. If I enter all values in the form it works perfectly fine. Can you see in the code below - where am i possibly going wrong ?

<script language="VB" runat="server" >

Sub Page_Load(Src As Object, e As EventArgs)


If Page.IsPostBack Then

Dim ConLath As SqlConnection
Dim comLath As SqlCommand
Dim insertcmd

conLath = New SqlConnection("Data Source=SQLas;Initial Catalog=settle;User ID=sa;Password=password")
ConLath.Open()
insertcmd = "Insert into His_set values (@.t_d,@.s_p,@.p_s,@.v_oq,@.i_oq,@.v_qn,@.i_qn,@.v_qw,@.i_qw)"

comLath = New SqlCommand(insertcmd, ConLath)


comLath.Parameters.Add(New SqlParameter("@.t_d", SqlDbType.DateTime, 12))
comLath.Parameters("@.t_d").Value = trade_date.Text
comLath.Parameters.Add(New SqlParameter("@.s_p", SqlDbType.Decimal, 8))
comLath.Parameters("@.s_p").Value = sett_price.Text
comLath.Parameters.Add(New SqlParameter("@.p_s", SqlDbType.Decimal, 8))
comLath.Parameters("@.p_s").Value = post_close.Text
comLath.Parameters.Add(New SqlParameter("@.v_oq", SqlDbType.Int, 8))
comLath.Parameters("@.v_oq").Value = vol_oq.Text
comLath.Parameters.Add(New SqlParameter("@.i_oq", SqlDbType.Int, 8))
comLath.Parameters("@.i_oq").Value = oi_oq.Text
comLath.Parameters.Add(New SqlParameter("@.v_qn", SqlDbType.Int, 8))
comLath.Parameters("@.v_qn").Value = vol_qn.Text
comLath.Parameters.Add(New SqlParameter("@.v_qw", SqlDbType.Int, 8))
comLath.Parameters("@.v_qw").Value = vol_qw.Text
comLath.Parameters.Add(New SqlParameter("@.i_qn", SqlDbType.Int, 8))
comLath.Parameters("@.i_qn").Value = oi_qn.Text
comLath.Parameters.Add(New SqlParameter("@.i_qw", SqlDbType.Int, 8))
comLath.Parameters("@.i_qw").Value = oi_qw.Text


Try
comLath.ExecuteNonQuery()

Catch ex As SqlException
If ex.Number = 2627 Then
Message.InnerHtml = "ERROR: A record already exists with " _
& "the same primary key"
Else
Message.InnerHtml = "ERROR: Could not add record, please " _
& "ensure the fields are correctly filled out"
Message.Style("color") = "red"
End If
End Try

comLath.Dispose()
ConLath.Close()




End If
End Sub

</script>

I'm not surprised if it fails when you leave the mandatory field empty. But I assume that's not what you meant, right?

The problem here relates to casting. Your empty text box returns an empty string. This would be fine for a varchar column, but if you try this with a column of type int, it will fail. You need to explicitly insert a null value in this case.

You could try something like this:

comLath.Parameters("@.v_oq").Value = (vol_oq.Text =="" ? DBNull.Value : vol_oq.Text);
|||

thanks for your prompt reply.

apparently the conditional operator ? works if u are using C#.

I am using the language vb, this implies i will have to use the if and then conditonal block for each, right?

|||
VB has the tertial operator IIF which is similar to ? operator, although it behaves somewhat differently (VB evaluates all parameters). 
comLath.Parameters("@.v_oq").Value = IIF(vol_oq.Text =="", DBNull.Value, vol_oq.Text)

|||

thanks so much it worked :)

however, the issue now is when i try to display the columns with null values, it reports an error -

i have explicitly casted these values with their corresponding data types to defualt value other than null. But the problem is like for eg, in case of any integer type it i set it to default of "0", for our business purpose its misleading as they would be expecting the sell of items for that day to be "0".

this is my code:

Public Function CheckDBNull(ByVal obj As Object, _
Optional ByVal ObjectType As enumObjectType = enumObjectType.StrType) As Object
Dim objReturn As Object
objReturn = obj
If ObjectType = enumObjectType.StrType And IsDBNull(obj) Then
objReturn = ""
ElseIf ObjectType = enumObjectType.IntType And IsDBNull(obj) Then
objReturn = 0
ElseIf ObjectType = enumObjectType.DblType And IsDBNull(obj) Then
objReturn = 0.0
End If
Return objReturn
End Function

|||

Then what do you want to display if an integer column is null? If you want to leave that field blank, simply return an empty string...

|||hi thanks for all your help... i have resolved the above query... much appreciated