Showing posts with label column. Show all posts
Showing posts with label column. Show all posts

Tuesday, March 27, 2012

Binding a SqlDataSource to a TextBox or label

I have a SQL database with 1 column in it.. it is a do not call registry for my office. I want to make a web application so our leads can go on the web and request to be put on the do not call list. problem is, if their number already exists, it gets a violation of primary key...

Normal handling for this would be to do a select query based on user input, and if it exists in the database, tell them that, else do the insert query...

Problem is, i cant seem to figure out how to bind the result of the select query to a textbox or label so i can compare the results to do that logic. Any ideas? This is in asp .net 2.0. Thanks!

-Dan

You can't directly bind to a Label or a TextBox, but you certainly can set the result of your DataSource to the Text property of your control. Here's an example:

ASPX

ProductName = <asp:label id="lblProductName" runat="server" /><asp:objectdatasource id="odsProducts" runat="server" selectmethod="GetProductByProductID"typename="NorthwindTableAdapters.ProductsTableAdapter"><selectparameters><asp:parameter defaultvalue="1" name="ProductID" type="Int32" /></selectparameters></asp:objectdatasource>

CODE-BEHIND

protected void Page_Load(object sender, EventArgs e){if (!this.IsPostBack){DataView dv = (DataView)odsProducts.Select();lblProductName.Text = dv[0]["ProductName"].ToString();}}

|||

Acctually... i figured out a way... check this out..

Dim dv As Data.DataView = SqlDataSource1.Select(DataSourceSelectArguments.Empty)

TextBox1.Text = dv.ToTable.Rows(0)("PHONE")

This works, but now i have another problem. If there is no row 0 (meaning if the number doesnt exist) the page fails. How can i check to see if the record doesnt exist, then do something else?

|||Just check to see if the DataView.Count property is greater than 0.|||Thanks, that worked great!

Binding a DataSource Table column to a form object (RadioButtons)

Hi,

I have a little question. I have an application which interfaces with a SQL Express Database. On a form, I want to bind a control which is made of several Radio buttons to a table column which is in fact a varchar(1). This is the picture:

Table column: OptVisualRpt varchar(1)

Screen control: 2 radio buttons

rb_VisRPTbImp_O for "yes"

rb_VisRPTbImp_N for "no"

I'm really scratching my head as how I can bind a single table column to my radio buttons controls. I think that I just can't this way but rather have to use an intermediate variable or control.

Solution 1?

I thought of using a local variable that I would set to "y" or "n" following "CheckedChanged" events fired from radio buttons but I don't know how to bind this variable to my table column.

Solution 2?

I thought of placing a hidden text control into my form, which one would be binded to my table column, that I would also set to "y" or "n" following "CheckedChanged" events fired from radio buttons.

Any of these solutions which would be feasible or any more neat way to do it?

Many thanks in advance,

Stphane

Hi again,

Finally sounds that last night I could solve my problem by myself. Let me explain.

1- I first got rid of the "Binding source". I removed following lines:

=> private: System::Windows::Forms::BindingSource ^ InfoBaseBindingSource;

=> this->InfoBaseBindingSource = (gcnew System::Windows::Forms::BindingSource(this->components));

=> (cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this->InfoBaseBindingSource))->BeginInit();

=> //
// InfoBaseBindingSource
//

this->InfoBaseBindingSource->DataMember = L"InfoBase";
this->InfoBaseBindingSource->DataSource = this->Test_ADODataSet;

=> (cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this->InfoBaseBindingSource))->EndInit();

2- At the same time, for every field control that were fed by it, I removed from code the following line (here is an example):

this->ID_Compagnie->DataBindings->Add((gcnew System::Windows::Forms::Binding(L"Text", this->InfoBaseBindingSource, L"Identification", true)));

3- I then changed the Form1_Load routine for the following:

this->InfoBaseTableAdapter->Fill(this->Test_ADODataSet->InfoBase);

DataTable ^ Dt_Infobase = this->Test_ADODataSet->Tables["InfoBase"];
if(Dt_Infobase != nullptr)
{
array<DataRow^> ^ Rw_InfoBase = Dt_Infobase->Select();
if(Rw_InfoBase->Length != 0)
{
this->ID_Compagnie->Text = Rw_InfoBase[0]["Identification"]->ToString();
this->Adr_Compagnie->Text = Rw_InfoBase[0]["Adresse"]->ToString();
...

==> Example of loading a masked text box

// Affichage et rectification du format du Code Postal/ZipCode

if(String::Compare(this->Pays_Compagnie->Text,"Canada") == 0)
{
this->CPZip_Compagnie->Mask = ">L0>L 0>L0";
this->Pnl_VSZCode->Hide();
}
else
{
this->Pnl_VSZCode->Show();
if(this->CPZip_Compagnie->Text->Length > 5)
{
this->VScrl_ZCode->Value = 1;
this->CPZip_Compagnie->Mask = "99999";
}
else
{
this->VScrl_ZCode->Value = 0;
this->CPZip_Compagnie->Mask = "99999-9999";
}
}

this->CPZip_Compagnie->Text = Rw_InfoBase[0]["CodePostal_Zip"]->ToString();

...

==> Example of "loading" info vs a set of radio buttons

String ^ Logo_ModeAff = Rw_InfoBase[0]["LogoRpt_ModeAff"]->ToString();
if(Logo_ModeAff == "C")
{
this->rb_ModeAffLCoord->Checked = true;
this->rb_ModeAffLOnly->Checked = false;
}
else
{
this->rb_ModeAffLCoord->Checked = false;
this->rb_ModeAffLOnly->Checked = true;
}
}

4- I then changed the B_Accept_Click routine for the following:

I removed following sentences:

this->InfoBaseBindingSource->EndEdit();
this->InfoBaseTableAdapter->Update(this->Test_ADODataSet->InfoBase);
this->Test_ADODataSet->AcceptChanges();

And replaced them with following:

DataTable ^ Dt_Infobase = this->Test_ADODataSet->Tables["InfoBase"];
if(Dt_Infobase != nullptr)
{
array<DataRow^> ^ Rw_InfoBase = Dt_Infobase->Select();
if(Rw_InfoBase->Length == 0)
{
DataRow ^ NRw_InfoBase = Dt_Infobase->NewRow();

NRw_InfoBase["Identification"] = this->ID_Compagnie->Text;
...
==> Example of a "saving" info vs a set of radio buttons

if(this->rb_ModeAffLCoord->Checked == true)
NRw_InfoBase["LogoRpt_ModeAff"] = "C";
else
NRw_InfoBase["LogoRpt_ModeAff"] = "L";
...

Dt_Infobase->Rows->Add(NRw_InfoBase);
}
else
{
Rw_InfoBase[0]["Identification"] = this->ID_Compagnie->Text;
...
==> Example of a "replacing" info vs a set of radio buttons

if(this->rb_ModeAffLCoord->Checked == true)
Rw_InfoBase[0]["LogoRpt_ModeAff"] = "C";
else
Rw_InfoBase[0]["LogoRpt_ModeAff"] = "L";
...
}

this->InfoBaseTableAdapter->Update(this->Test_ADODataSet);
this->Test_ADODataSet->AcceptChanges();
}

5- I finally changed the B_Cancel_Click routine for the following:

I removed following sentences:

this->InfoBaseBindingSource->EndEdit();

This code is maybe not the best way to do it. If someone has any more proper way to do it, I would certainly appreciate to learn. My conclusion is that doing this binding process manually gives better results than relying on a BindingSource object.

Stphane

Sunday, March 25, 2012

Binary_Checksum - How secure is it?

Hi,
In one of my client's database some confidential information is stored in an
encrypted format and a different column has the original value in a
Binary_Checksum format.
For example, if 'abc' is a password, its first encrypted and put in Column1.
But a Binary_Checksum of 'abc' is stored in Column2 for comparison purposes.
I am just wondering whether this is secure. Can't the Binary_Checksum value
(26435) be reversed to get the original 'abc'?
Thank you.
Regards,
KarthikHi Karthik,
The hashes generated are only 32 bits long, which is tiny. BOL states that
the probability of a collision is higher than that of the MD5 one-way hash
function, which itself is considered insecure at this point. This means a
hacker has a much greater chance of guessing the password with brute force
or dictionary attacks. Consider the following sample run in SQL 2005:
SELECT BINARY_CHECKSUM('AAAAAAAAAAAAAAAAA')
SELECT BINARY_CHECKSUM('A')
The first thing to notice is the simplicity of the algorithm.
BINARY_CHECKSUM('A') returns 65, which is the ASCII code for.. what else?
'A'. Both of the SELECT statements above produce the same result. Someone
trying to hack this particular system where you use BINARY_CHECKSUM to hash
the password will have a pretty easy time of getting some generated string
to match that hash. I would switch to another hash algorithm like SHA or
something.
"Karthik" <Karthik@.discussions.microsoft.com> wrote in message
news:0AC981BD-2919-496D-9572-D7F5EA38F3A8@.microsoft.com...
> Hi,
> In one of my client's database some confidential information is stored in
> an
> encrypted format and a different column has the original value in a
> Binary_Checksum format.
> For example, if 'abc' is a password, its first encrypted and put in
> Column1.
> But a Binary_Checksum of 'abc' is stored in Column2 for comparison
> purposes.
> I am just wondering whether this is secure. Can't the Binary_Checksum
> value
> (26435) be reversed to get the original 'abc'?
> Thank you.
> Regards,
> Karthik|||Karthik (Karthik@.discussions.microsoft.com) writes:
> In one of my client's database some confidential information is stored
> in an encrypted format and a different column has the original value in
> a Binary_Checksum format.
> For example, if 'abc' is a password, its first encrypted and put in
> Column1. But a Binary_Checksum of 'abc' is stored in Column2 for
> comparison purposes.
> I am just wondering whether this is secure. Can't the Binary_Checksum
> value (26435) be reversed to get the original 'abc'?
I believe the checksum algorithm is not very sophisticated at all, it only
performs some XOR operations. Then again, it's a destroying
transformation. There are many strings that gets the same checksum. So
it's not completely trivial to guess the original text. Unless, of
course, you already have an idea of what it could be.
So it's not certainly not as secure as a real encrypted value.
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx|||You need to educate them on the definition of "encrypted" versus "encoded".
It's generally accepted that encrypted means some type of key is required to
decrypt the data, whether it's a certificate or a password. Encoded means no
key is required. You're talking about encoded here.
Ray

> In one of my client's database some confidential information is stored in
> an
> encrypted format|||Any checksum is simply Character by Character XOR. This is the same as for
RAID parity, .zip checksums, etc. It is not intended to be used for
encryption.
It is based on the fact that the XOR operator is commutative and transitive:
A XOR B = C = B XOR A,
B XOR C = A = C XOR B, and
C XOR A = B = A XOR C,
Which is why PARITY works.
Encryption works the same way, which is why you can decrypt. However, to
make it more secure, instead of XORing the characters together, the original
values are XORed with a fixed algorithm hash. The method of constructing
this hash is what determines the strength of the algorithm.
The hash for a checksum is 0, which is extremely simple to hack: I just told
you what it was; no big secret.
Sincerely,
Anthony Thomas
"Karthik" <Karthik@.discussions.microsoft.com> wrote in message
news:0AC981BD-2919-496D-9572-D7F5EA38F3A8@.microsoft.com...
> Hi,
> In one of my client's database some confidential information is stored in
an
> encrypted format and a different column has the original value in a
> Binary_Checksum format.
> For example, if 'abc' is a password, its first encrypted and put in
Column1.
> But a Binary_Checksum of 'abc' is stored in Column2 for comparison
purposes.
> I am just wondering whether this is secure. Can't the Binary_Checksum
value
> (26435) be reversed to get the original 'abc'?
> Thank you.
> Regards,
> Karthik|||Hi Mike, Erland, Ray and Anthony,
Thank you for all the valuable input. I will present these facts to my
client. Hopefully he will agree for a proper hash rather than
binary_checksum()
Thank you!
Regards,
Karthik
"Mike C#" wrote:

> Hi Karthik,
> The hashes generated are only 32 bits long, which is tiny. BOL states tha
t
> the probability of a collision is higher than that of the MD5 one-way hash
> function, which itself is considered insecure at this point. This means a
> hacker has a much greater chance of guessing the password with brute force
> or dictionary attacks. Consider the following sample run in SQL 2005:
> SELECT BINARY_CHECKSUM('AAAAAAAAAAAAAAAAA')
> SELECT BINARY_CHECKSUM('A')
> The first thing to notice is the simplicity of the algorithm.
> BINARY_CHECKSUM('A') returns 65, which is the ASCII code for.. what else?
> 'A'. Both of the SELECT statements above produce the same result. Someon
e
> trying to hack this particular system where you use BINARY_CHECKSUM to has
h
> the password will have a pretty easy time of getting some generated string
> to match that hash. I would switch to another hash algorithm like SHA or
> something.
> "Karthik" <Karthik@.discussions.microsoft.com> wrote in message
> news:0AC981BD-2919-496D-9572-D7F5EA38F3A8@.microsoft.com...
>
>

binary varbinary question

What is the documented and known behavior of inserting hex constants into a
binary/varbinary column from a client to a server which have different code
pages? Will any code page / character set conversion take place?
eg: insert into t1 values ('AA') or insert into t1 values(x'AA')
Thanks
AakashYou can specify a binary (hex) constant as 0x followed by the character
representation of the hex string. These are not enclosed in quotes.
For example:

INSERT INTO t1 VALUES(0xAA)

This is documented in the SQL Server 2000 Books Online
<tsqlref.chm::/ts_ca-co_1n1v.htm>. Since the value is not a character
value, no character conversion occurs.

--
Hope this helps.

Dan Guzman
SQL Server MVP

--------
SQL FAQ links (courtesy Neil Pike):

http://www.ntfaq.com/Articles/Index...epartmentID=800
http://www.sqlserverfaq.com
http://www.mssqlserver.com/faq
--------

"Aakash Bordia" <a_bordia@.hotmail.com> wrote in message
news:bf4j62$688$1@.hanover.torolab.ibm.com...
> What is the documented and known behavior of inserting hex constants
into a
> binary/varbinary column from a client to a server which have different
code
> pages? Will any code page / character set conversion take place?
> eg: insert into t1 values ('AA') or insert into t1 values(x'AA')
> Thanks
> Aakash

Binary to Varchar

I am trying to conver a binary column in the source table to a varchar as sh
own
select convert(varchar(32),0x00000000000003F3) it retunrns a null
hoe do i go about doing it?
Thankssatya wrote:
> I am trying to conver a binary column in the source table to a varchar as
shown
> select convert(varchar(32),0x00000000000003F3) it retunrns a null
> hoe do i go about doing it?
The following works for me:
select convert(varchar(32), convert(int, 0x00000000000003F3))

Binary Problem

Hy friends!

I'm new in WebApplications that have SQL SERVER DB.

My problem is that...

In the DataBase I have a table with varbinary column and in the program I want save in this column a value of binary[] variable! How I can make it?

Another question... If I want select (by a query in the application) the value of the binary column, where I store it? because if I want select an integer value I take this in a int variable, and if I want select an string value from a DataBase I take this in a string variable..but How I can make it with binary column?

Thanks in advance!!

The following Scott Mitchell tutorial should help you

http://aspnet.4guysfromrolla.com/articles/081705-1.2.aspx

sql

Thursday, March 22, 2012

Binary Column always returns 0 for ISNULL

Why don't i ever get return value of 1 when the following binary column (profSignature) is null?

RETURN SELECT ISNULL

(profSignature, profSignature)FROMmpProfilesWHEREApplicantID =CAST(@.CIDAS INT)ANDProfileID =CAST(@.PIDAS INT)

There is no conversion between GUID and INT that is what I think you are trying to do, try the link below for SQL Server data type conversion chart. Hope this helps.

http://msdn2.microsoft.com/en-us/library/ms187928.aspx

|||I forgot to add that the column type is "Image" in SQL 2005|||

Dup post

|||How would I get it so a <NULL> column value makes the stored procedure return 1 or 0?|||

I have checked the conversion chart again that is not valid either so check the create table statement below from Microsoft AdventureWorks it pick the columns relevant to your situation and you can get the information you are looking for. Sorry about the duplicate post. Hope this helps.

CREATE TABLE [EmployeePhoto] (
[EmployeePhotoID] [int] IDENTITY (1, 1) NOT NULL ,
[ThumbNailPhoto] [image] NULL ,
[ThumbnailPhotoFileName] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[LargePhoto] [image] NULL ,
[LargePhotoFileName] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[ModifiedDate] [datetime] NOT NULL CONSTRAINT [DF_EmployeePhoto_ModifiedDate] DEFAULT (getdate()),
CONSTRAINT [PK_EmployeePhoto_EmployeePhotoID] PRIMARY KEY CLUSTERED
(
[EmployeePhotoID]
) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

|||

If you need 1 on null try this:

RETURN SELECT ISNULL(profSignature,1)
FROMmpProfiles
WHEREApplicantID =CAST(@.CIDAS INT)
ANDProfileID =CAST(@.PIDAS INT)

or

RETURN (case
when exist(Select * FROMmpProfiles
WHEREApplicantID =CAST(@.CIDAS INT)
ANDProfileID =CAST(@.PIDAS INT)
and profSignature is null) then 1 -- for null

when exist(Select * FROMmpProfiles
WHEREApplicantID =CAST(@.CIDAS INT)
ANDProfileID =CAST(@.PIDAS INT)
and not profSignature is null) then 2 -- for not nulls

else

0 -- does not exists in database

end)

|||Thanks ... the case statement did the trick.sql

Binary column

We have a binary column that stores web passwords.
What is the proper way to access this column?
The sql below is blowing up!
UPDATE AppServices.dbo.DBUsers
SET Password = 'MyPassword'
WHERE UserId ='MyLogin'Here is one way to accomplish this task.
UPDATE AppServices.dbo.DBUsers
SET Password = pwdencrypt('MyPassword')
WHERE UserId ='MyLogin'
pwdencrypt and pwdcompare are two undocumented SQL functions.
"Arne" <Arne@.discussions.microsoft.com> wrote in message
news:E269D86B-E84E-45CE-8E33-81D483391080@.microsoft.com...
> We have a binary column that stores web passwords.
> What is the proper way to access this column?
> The sql below is blowing up!
> UPDATE AppServices.dbo.DBUsers
> SET Password = 'MyPassword'
> WHERE UserId ='MyLogin'

Binary (Image) in SSAS

I have an Image column in my database nicely imported by SSIS. I want to use these (product) images in my reports. These reports use a SSAS cube as source.

However, I'm unable to use this column as an attribute of my dimension. I get the error:
The 'Binary' data type is not allowed for the 'KeyColumns' property #0

I know there are alternatives like only storing the location of the file and using the url to get it, but that's not an option for me.

Thank you very much!Still nobody who can awnser this? |||

Look in the Adventure Works sample cubes in the Product dimension. They've got the logo image in there. The trick is to put an int ID as the KeyColumn and use the image datatype as the MemberValue.

Binary (Image) in SSAS

I have an Image column in my database nicely imported by SSIS. I want to use these (product) images in my reports. These reports use a SSAS cube as source.

However, I'm unable to use this column as an attribute of my dimension. I get the error:
The 'Binary' data type is not allowed for the 'KeyColumns' property #0

I know there are alternatives like only storing the location of the file and using the url to get it, but that's not an option for me.

Thank you very much!Still nobody who can awnser this? |||

Look in the Adventure Works sample cubes in the Product dimension. They've got the logo image in there. The trick is to put an int ID as the KeyColumn and use the image datatype as the MemberValue.

Binary

Hi,
I have a column that contains binary representation of numbers. For example
'10' for 2 and '11' for 3 and ...
I wanted to write a function to convert this column to INT but I thought
there might be a built-in function in SQL Server.
Are there any function?
Thanks in advance,
LeilaHi
You should be able to cast this directly!
DECLARE @.bin varbinary(10)
SET @.bin = 2
SELECT @.bin, cast(@.bin as int )
John
"Leila" wrote:

> Hi,
> I have a column that contains binary representation of numbers. For exampl
e
> '10' for 2 and '11' for 3 and ...
> I wanted to write a function to convert this column to INT but I thought
> there might be a built-in function in SQL Server.
> Are there any function?
> Thanks in advance,
> Leila
>
>|||Leila,
There is an undocumented system function fn_replbitstringtoint()
that will do this, if you pad your column value by adding '0's on
the left to make it 32 characters long. Here are some examples:
select fn_replbitstringtoint('00000000000000000
000000000000011')
select fn_replbitstringtoint('1')
select fn_replbitstringtoint(right(replicate('0
',32)+'1',32))
declare @.yourBits varchar(32)
set @.yourBits = '1101'
select fn_replbitstringtoint(right(replicate('0
',32)+@.yourBits,32))
Since this function is not documented, it is not supported and
may not exist or work the same way in the future. You should
not use it in production code.
You can write an equivalent function as a user-defined function.
Here's a newsgroup thread that should help:
http://groups.google.co.uk/groups?q...tstring+integer
Steve Kass
Drew University
Leila wrote:

>Hi,
>I have a column that contains binary representation of numbers. For example
>'10' for 2 and '11' for 3 and ...
>I wanted to write a function to convert this column to INT but I thought
>there might be a built-in function in SQL Server.
>Are there any function?
>Thanks in advance,
>Leila
>
>|||John,
Leila has the input string '10'. If she already had the
value 2 as input, she wouldn't need to do this. I don't
think there is any conversion using CAST() that will
produce 2 as the result of CAST('10' as ').
Your example produces the integer 2 in the statement
SET @.bin = 2, not in the CAST() operation, and in order
to do SET @.bin = 2, you must already have the answer.
Leila needs something to fill in the gap here:
declare @.columnValue varchar(32)
set @.columnValue = '10'
declare @.result int
'? -- @.result gets the value 2, without your typing 2
select @.result
SK
John Bell wrote:
>Hi
>You should be able to cast this directly!
>DECLARE @.bin varbinary(10)
>SET @.bin = 2
>SELECT @.bin, cast(@.bin as int )
>John
>"Leila" wrote:
>
>|||I am not sure how I miss-interpreted that!
"Steve Kass" wrote:

> John,
> Leila has the input string '10'. If she already had the
> value 2 as input, she wouldn't need to do this. I don't
> think there is any conversion using CAST() that will
> produce 2 as the result of CAST('10' as ').
> Your example produces the integer 2 in the statement
> SET @.bin = 2, not in the CAST() operation, and in order
> to do SET @.bin = 2, you must already have the answer.
> Leila needs something to fill in the gap here:
> declare @.columnValue varchar(32)
> set @.columnValue = '10'
> declare @.result int
> '? -- @.result gets the value 2, without your typing 2
> select @.result
> SK
> John Bell wrote:
>
>|||Thanks Steve :-)
"Steve Kass" <skass@.drew.edu> wrote in message
news:OZckRZrjFHA.3960@.TK2MSFTNGP12.phx.gbl...
> Leila,
> There is an undocumented system function fn_replbitstringtoint()
> that will do this, if you pad your column value by adding '0's on
> the left to make it 32 characters long. Here are some examples:
> select fn_replbitstringtoint('00000000000000000
000000000000011')
> select fn_replbitstringtoint('1')
> select fn_replbitstringtoint(right(replicate('0
',32)+'1',32))
> declare @.yourBits varchar(32)
> set @.yourBits = '1101'
> select fn_replbitstringtoint(right(replicate('0
',32)+@.yourBits,32))
> Since this function is not documented, it is not supported and
> may not exist or work the same way in the future. You should
> not use it in production code.
> You can write an equivalent function as a user-defined function.
> Here's a newsgroup thread that should help:
> http://groups.google.co.uk/groups?q...tstring+integer
> Steve Kass
> Drew University
>
> Leila wrote:
>
example|||Why are you doing assembly level programming in SQL? The whole idea of
a database was to separate data from application code with a layer or
two of abstractions between them. You should not be worrying about
things like this.|||Joe,
This is the legacy data and I'm trying to transform it!
Thanks.
"--CELKO--" <jcelko212@.earthlink.net> wrote in message
news:1122068660.835679.173370@.z14g2000cwz.googlegroups.com...
> Why are you doing assembly level programming in SQL? The whole idea of
> a database was to separate data from application code with a layer or
> two of abstractions between them. You should not be worrying about
> things like this.
>|||I would think about getting a low level language like C or something
and move it over to a CSV file that you can edit before it goes into
your SQL data base. The data is probably a mess.

Tuesday, March 20, 2012

Big problem with triggers

I have little problem and I dont have any idea how to make my trigger.

I have table MyTable where I have many column with almost same name and same
type (Grp1,Grp2,Grp3,Grp4...Grp50 char(1)).
I`d like to make some trigger on UPDATE this table. I must to check which
column was changed.

For example to check if Grp1 was changed I can try this:

ALTER TRIGGER MyTrigger
ON MyTable
AFTER UPDATE
AS
DECLARE @.OldValue char(1)
DECLARE @.NewValue char(1)
BEGIN
SET @.OldValue = (SELECT Grp1 FROM DELETED)
SET @.NewValue = (SELECT Grp1 FROM INSERTED)

IF (@.OldValue <> @.NewValue)
BEGIN
...
...
...
END
END

Of course I can do this step by step, for all columns, but it`s not good
option.
I tried to make this trigger more dynamicaly, but this not worked (Server:
Msg 208, Level 16, State 1, Line 1
Invalid object name 'DELETED'.)

ALTER TRIGGER MyTrigger
ON MyTable
AFTER UPDATE
AS
DECLARE @.OldValue char(1)
DECLARE @.NewValue char(1)
DECLARE @.MyQry VarChar(1000)
DECLARE @.ActGrp VarChar(2)
BEGIN
@.ActGrp = '1'
SET @.MyQry ='
SET @.OldValue = (SELECT Grp'+@.ActGrp+' FROM DELETED)
SET @.NewValue = (SELECT Grp'+@.ActGrp+' FROM INSERTED)

IF (@.OldValue <> @.NewValue)
BEGIN
...
...
...
END
'
END

:(

Can anybody help me? How can I easy check all Grp1...Grp50 to know where
colums was changed?Hi

Triggers are activated on a statement and not per row changed, therefore the
use of variables in your trigger to store old and new values will not
produce predictable results.

In general it is better to keep your triggers as short as possible to avoid
prolonging your transactions. If you are trying to produce and audit trail
then I would keep the comparisons external to the trigger and follow the
example of auditing in
http://msdn.microsoft.com/library/d...create_4hk5.asp

John

"BUSHII" <piotrl@.robcom.com.pl> wrote in message
news:cbbcqa$g62$1@.atlantis.news.tpi.pl...
> I have little problem and I dont have any idea how to make my trigger.
> I have table MyTable where I have many column with almost same name and
same
> type (Grp1,Grp2,Grp3,Grp4...Grp50 char(1)).
> I`d like to make some trigger on UPDATE this table. I must to check which
> column was changed.
> For example to check if Grp1 was changed I can try this:
> ALTER TRIGGER MyTrigger
> ON MyTable
> AFTER UPDATE
> AS
> DECLARE @.OldValue char(1)
> DECLARE @.NewValue char(1)
> BEGIN
> SET @.OldValue = (SELECT Grp1 FROM DELETED)
> SET @.NewValue = (SELECT Grp1 FROM INSERTED)
>
> IF (@.OldValue <> @.NewValue)
> BEGIN
> ...
> ...
> ...
> END
> END
>
> Of course I can do this step by step, for all columns, but it`s not good
> option.
> I tried to make this trigger more dynamicaly, but this not worked (Server:
> Msg 208, Level 16, State 1, Line 1
> Invalid object name 'DELETED'.)
> ALTER TRIGGER MyTrigger
> ON MyTable
> AFTER UPDATE
> AS
> DECLARE @.OldValue char(1)
> DECLARE @.NewValue char(1)
> DECLARE @.MyQry VarChar(1000)
> DECLARE @.ActGrp VarChar(2)
> BEGIN
> @.ActGrp = '1'
> SET @.MyQry ='
> SET @.OldValue = (SELECT Grp'+@.ActGrp+' FROM DELETED)
> SET @.NewValue = (SELECT Grp'+@.ActGrp+' FROM INSERTED)
>
> IF (@.OldValue <> @.NewValue)
> BEGIN
> ...
> ...
> ...
> END
> '
> END
> :(
> Can anybody help me? How can I easy check all Grp1...Grp50 to know where
> colums was changed?sql

Monday, March 19, 2012

BIDS - How to turn-off auto naming of fields

Hi:

When I create a report, the wizard auto-renames fields.

E.g. if Table_COLUMN_Name=CustomerName, the list column header in the report will change to Customer Name. The wizard figures out Friendly names based on capitalization, and underscores and so on.

Similar behavior occurs even in SSAS projects Dimensions Wizard.

Is there a way to turn of this extra cuteness?

TIA

Kar

Hi:

Request help once again on this.

TIA

Kar

Sunday, March 11, 2012

BIDS - How to turn-off auto naming of fields

Hi:

When I create a report, the wizard auto-renames fields.

E.g. if Table_COLUMN_Name=CustomerName, the list column header in the report will change to Customer Name. The wizard figures out Friendly names based on capitalization, and underscores and so on.

Similar behavior occurs even in SSAS projects Dimensions Wizard.

Is there a way to turn of this extra cuteness?

TIA

Kar

Hi:

Request help once again on this.

TIA

Kar

Wednesday, March 7, 2012

beware of avg() for large datasets

Not a question, just a post about something I ran into today that surprised me a little.

I have a huge dataset - about 700m rows, one column of which is a tinyint. I needed to take an average of that column, so I did this:

select avg(mytinyint) from mytable

which returned:

Msg 8115, Level 16, State 2, Line 6
Arithmetic overflow error converting expression to data type int.

It turns out, if the sum() over the column is bigger than MAX_INT = 2147483647, then avg() will throw this error. This surprised me a little - I guess I was assuming sql server would use bigint internally when computing integer avg, but it uses int.

so you have to do this:

select avg(cast(mytinyint as bigint)) from mytable

what's annoying to me is, it's impossible that an average of type T could be larger or smaller than the max/min allowed value of a type T. This means sql server devs could have internally always used bigint for sum and count, and then returned cast(sum/count as T) from avg() without possibility of overflow (unless sum or count was bigger than the max bigint! you are on your own if that happens i guess!).

Because of this, you have to cast your column to a bigint to make it work if your dataset is large enough, even if the column is only 1 measly byte! kind of a waste of space if you ask me. :)

here's a little example of what I'm talking about, that doesn't require you to import a 700m row dataset :)

declare @.t table (id int)
insert into @.t select 1 union all select 2147483647
select avg(cast(id as bigint)) from @.t -- works
select avg(id) from @.t -- failshmm...:rolleyes:|||Very interesting. I will check it out tomorrow. Thanks for posting it.

BETWEEN returns invalid data

I'm using BETWEEN stmt to retrieve data from a varchar column code,
so suppose this column contains mainly numbers,( i.e. 40, 300, 400, 500)
and the stmt is:
Select * from table where code between '300' and '500'
the result returns 40 also, so this is not an effective way to retrieve such data.
so how to make this work out.

Best Regards,

Quote:

Originally Posted by theavitor

I'm using BETWEEN stmt to retrieve data from a varchar column code,
so suppose this column contains mainly numbers,( i.e. 40, 300, 400, 500)
and the stmt is:
Select * from table where code between '300' and '500'
the result returns 40 also, so this is not an effective way to retrieve such data.
so how to make this work out.

Best Regards,


Try Greater than 300 and less than 500 like the following:
Select * from table where code > '300' and code < '500'

what do you get?|||Hi ,

Plz try this . . .

Select * from table where convert(numeric,code) between 300 and 500. This query will wrk properly. or else mail me at mneduu@.gmail.com|||PLease try this

Select * from table where code between 300 and 500. This query will work.
I've already try this

and this quesry will also work

Select * from table where convert(numeric,code) between 300 and 500.

Saturday, February 25, 2012

Between Clause

Hai,
I have a table with datetime type column. I stored the date with time in
this column.
Now i want to select the records between 10/01/2005 and 10/31/2005.
I used 'select * from tablename where columnname between '10/01/2005' and
'10/31/2005'' query to select records.
But the above query returns upto 10/30/2005.
Please advise me.
Rgds,
SouraThis works fine for me.
create table test(id int, testdate datetime)
insert into test values(1, '10/01/2005')
insert into test values(1, '10/10/2005')
insert into test values(1, '10/31/2005')
select * from test where testdate between '10/01/2005' and '10/31/2005'
Please post you data and ddl.
Thanks
Amish
*** Sent via Developersdex http://www.developersdex.com ***|||This should contain all necessary information: http://www.karaszi.com/SQLServer/info_datetime.asp
--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/
Blog: http://solidqualitylearning.com/blogs/tibor/
"SouRa" <SouRa@.discussions.microsoft.com> wrote in message
news:C2DF4191-4BD9-4A6B-AB94-2D16F715E493@.microsoft.com...
> Hai,
> I have a table with datetime type column. I stored the date with time in
> this column.
> Now i want to select the records between 10/01/2005 and 10/31/2005.
> I used 'select * from tablename where columnname between '10/01/2005' and
> '10/31/2005'' query to select records.
> But the above query returns upto 10/30/2005.
> Please advise me.
> Rgds,
> Soura|||Soura,
'10/31/2005' assumes 10/31/2005 at midnight. Any records with a time of
after midnight will not be included in the results.
Try:
select *
from tablename
where columnname between '10/01/2005' and '10/31/2005 23:59:59'
Rob
SouRa wrote:
> Hai,
> I have a table with datetime type column. I stored the date with time in
> this column.
> Now i want to select the records between 10/01/2005 and 10/31/2005.
> I used 'select * from tablename where columnname between '10/01/2005' and
> '10/31/2005'' query to select records.
> But the above query returns upto 10/30/2005.
> Please advise me.
> Rgds,
> Soura|||> select *
> from tablename
> where columnname between '10/01/2005' and '10/31/2005 23:59:59'
or between '10/01/2005' and '10/31/2005 23:59:59.997'
to capture everything in the last day.
--
William Stacey [MVP]|||Hi Rob,
Thanks for your response, it is working fine. But i get the inputs only in
date format('10/01/2005'), So i want to concatenate the timestamp each time.
I have one method,
"select * from table_name where
convert(datetime,convert(varchar,column_name) ) between '10/01/2005' and
'10/31/2005'
it is working fine.
Can you tell me it is efficient one. Please advise me.
rgds,
Soura
"Rob" wrote:
> Soura,
> '10/31/2005' assumes 10/31/2005 at midnight. Any records with a time of
> after midnight will not be included in the results.
> Try:
> select *
> from tablename
> where columnname between '10/01/2005' and '10/31/2005 23:59:59'
> Rob
> SouRa wrote:
> > Hai,
> >
> > I have a table with datetime type column. I stored the date with time in
> > this column.
> > Now i want to select the records between 10/01/2005 and 10/31/2005.
> >
> > I used 'select * from tablename where columnname between '10/01/2005' and
> > '10/31/2005'' query to select records.
> >
> > But the above query returns upto 10/30/2005.
> >
> > Please advise me.
> >
> > Rgds,
> > Soura
>|||Hi William ,
Thanks for your response, it is working fine. But i get the inputs only in
date format('10/01/2005'), So i want to concatenate the timestamp each time.
I have one method,
"select * from table_name where
convert(datetime,convert(varchar,column_name) ) between '10/01/2005' and
'10/31/2005'
it is working fine.
Can you tell me it is efficient one. Please advise me.
rgds,
Soura
"William Stacey [MVP]" wrote:
> > select *
> > from tablename
> > where columnname between '10/01/2005' and '10/31/2005 23:59:59'
> or between '10/01/2005' and '10/31/2005 23:59:59.997'
> to capture everything in the last day.
> --
> William Stacey [MVP]
>
>|||Did you read my article?
> "select * from table_name where
> convert(datetime,convert(varchar,column_name) ) between '10/01/2005' and
> '10/31/2005'
Above will negate the usage of indexes on the column. Can potentially be disastrous for performance.
--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/
Blog: http://solidqualitylearning.com/blogs/tibor/
"SouRa" <SouRa@.discussions.microsoft.com> wrote in message
news:CD781D5B-4FF2-49B5-B673-A47EC0A60E7E@.microsoft.com...
> Hi Rob,
> Thanks for your response, it is working fine. But i get the inputs only in
> date format('10/01/2005'), So i want to concatenate the timestamp each time.
> I have one method,
> "select * from table_name where
> convert(datetime,convert(varchar,column_name) ) between '10/01/2005' and
> '10/31/2005'
> it is working fine.
> Can you tell me it is efficient one. Please advise me.
> rgds,
> Soura
> "Rob" wrote:
>> Soura,
>> '10/31/2005' assumes 10/31/2005 at midnight. Any records with a time of
>> after midnight will not be included in the results.
>> Try:
>> select *
>> from tablename
>> where columnname between '10/01/2005' and '10/31/2005 23:59:59'
>> Rob
>> SouRa wrote:
>> > Hai,
>> >
>> > I have a table with datetime type column. I stored the date with time in
>> > this column.
>> > Now i want to select the records between 10/01/2005 and 10/31/2005.
>> >
>> > I used 'select * from tablename where columnname between '10/01/2005' and
>> > '10/31/2005'' query to select records.
>> >
>> > But the above query returns upto 10/30/2005.
>> >
>> > Please advise me.
>> >
>> > Rgds,
>> > Soura

Between Clause

Hai,
I have a table with datetime type column. I stored the date with time in
this column.
Now i want to select the records between 10/01/2005 and 10/31/2005.
I used 'select * from tablename where columnname between '10/01/2005' and
'10/31/2005'' query to select records.
But the above query returns upto 10/30/2005.
Please advise me.
Rgds,
Soura
This works fine for me.
create table test(id int, testdate datetime)
insert into test values(1, '10/01/2005')
insert into test values(1, '10/10/2005')
insert into test values(1, '10/31/2005')
select * from test where testdate between '10/01/2005' and '10/31/2005'
Please post you data and ddl.
Thanks
Amish
*** Sent via Developersdex http://www.codecomments.com ***
|||This should contain all necessary information: http://www.karaszi.com/SQLServer/info_datetime.asp
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/
Blog: http://solidqualitylearning.com/blogs/tibor/
"SouRa" <SouRa@.discussions.microsoft.com> wrote in message
news:C2DF4191-4BD9-4A6B-AB94-2D16F715E493@.microsoft.com...
> Hai,
> I have a table with datetime type column. I stored the date with time in
> this column.
> Now i want to select the records between 10/01/2005 and 10/31/2005.
> I used 'select * from tablename where columnname between '10/01/2005' and
> '10/31/2005'' query to select records.
> But the above query returns upto 10/30/2005.
> Please advise me.
> Rgds,
> Soura
|||Soura,
'10/31/2005' assumes 10/31/2005 at midnight. Any records with a time of
after midnight will not be included in the results.
Try:
select *
from tablename
where columnname between '10/01/2005' and '10/31/2005 23:59:59'
Rob
SouRa wrote:
> Hai,
> I have a table with datetime type column. I stored the date with time in
> this column.
> Now i want to select the records between 10/01/2005 and 10/31/2005.
> I used 'select * from tablename where columnname between '10/01/2005' and
> '10/31/2005'' query to select records.
> But the above query returns upto 10/30/2005.
> Please advise me.
> Rgds,
> Soura
|||> select *
> from tablename
> where columnname between '10/01/2005' and '10/31/2005 23:59:59'
or between '10/01/2005' and '10/31/2005 23:59:59.997'
to capture everything in the last day.
William Stacey [MVP]
|||Hi Rob,
Thanks for your response, it is working fine. But i get the inputs only in
date format('10/01/2005'), So i want to concatenate the timestamp each time.
I have one method,
"select * from table_name where
convert(datetime,convert(varchar,column_name) ) between '10/01/2005' and
'10/31/2005'
it is working fine.
Can you tell me it is efficient one. Please advise me.
rgds,
Soura
"Rob" wrote:

> Soura,
> '10/31/2005' assumes 10/31/2005 at midnight. Any records with a time of
> after midnight will not be included in the results.
> Try:
> select *
> from tablename
> where columnname between '10/01/2005' and '10/31/2005 23:59:59'
> Rob
> SouRa wrote:
>
|||Hi William ,
Thanks for your response, it is working fine. But i get the inputs only in
date format('10/01/2005'), So i want to concatenate the timestamp each time.
I have one method,
"select * from table_name where
convert(datetime,convert(varchar,column_name) ) between '10/01/2005' and
'10/31/2005'
it is working fine.
Can you tell me it is efficient one. Please advise me.
rgds,
Soura
"William Stacey [MVP]" wrote:

> or between '10/01/2005' and '10/31/2005 23:59:59.997'
> to capture everything in the last day.
> --
> William Stacey [MVP]
>
>
|||Did you read my article?

> "select * from table_name where
> convert(datetime,convert(varchar,column_name) ) between '10/01/2005' and
> '10/31/2005'
Above will negate the usage of indexes on the column. Can potentially be disastrous for performance.
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/
Blog: http://solidqualitylearning.com/blogs/tibor/
"SouRa" <SouRa@.discussions.microsoft.com> wrote in message
news:CD781D5B-4FF2-49B5-B673-A47EC0A60E7E@.microsoft.com...[vbcol=seagreen]
> Hi Rob,
> Thanks for your response, it is working fine. But i get the inputs only in
> date format('10/01/2005'), So i want to concatenate the timestamp each time.
> I have one method,
> "select * from table_name where
> convert(datetime,convert(varchar,column_name) ) between '10/01/2005' and
> '10/31/2005'
> it is working fine.
> Can you tell me it is efficient one. Please advise me.
> rgds,
> Soura
> "Rob" wrote:

Between Clause

Hai,
I have a table with datetime type column. I stored the date with time in
this column.
Now i want to select the records between 10/01/2005 and 10/31/2005.
I used 'select * from tablename where columnname between '10/01/2005' and
'10/31/2005'' query to select records.
But the above query returns upto 10/30/2005.
Please advise me.
Rgds,
SouraThis works fine for me.
create table test(id int, testdate datetime)
insert into test values(1, '10/01/2005')
insert into test values(1, '10/10/2005')
insert into test values(1, '10/31/2005')
select * from test where testdate between '10/01/2005' and '10/31/2005'
Please post you data and ddl.
Thanks
Amish
*** Sent via Developersdex http://www.codecomments.com ***|||This should contain all necessary information: http://www.karaszi.com/SQLServer/in...fo_datetime.asp
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/
Blog: http://solidqualitylearning.com/blogs/tibor/
"SouRa" <SouRa@.discussions.microsoft.com> wrote in message
news:C2DF4191-4BD9-4A6B-AB94-2D16F715E493@.microsoft.com...
> Hai,
> I have a table with datetime type column. I stored the date with time in
> this column.
> Now i want to select the records between 10/01/2005 and 10/31/2005.
> I used 'select * from tablename where columnname between '10/01/2005' and
> '10/31/2005'' query to select records.
> But the above query returns upto 10/30/2005.
> Please advise me.
> Rgds,
> Soura|||Soura,
'10/31/2005' assumes 10/31/2005 at midnight. Any records with a time of
after midnight will not be included in the results.
Try:
select *
from tablename
where columnname between '10/01/2005' and '10/31/2005 23:59:59'
Rob
SouRa wrote:
> Hai,
> I have a table with datetime type column. I stored the date with time in
> this column.
> Now i want to select the records between 10/01/2005 and 10/31/2005.
> I used 'select * from tablename where columnname between '10/01/2005' and
> '10/31/2005'' query to select records.
> But the above query returns upto 10/30/2005.
> Please advise me.
> Rgds,
> Soura|||> select *
> from tablename
> where columnname between '10/01/2005' and '10/31/2005 23:59:59'
or between '10/01/2005' and '10/31/2005 23:59:59.997'
to capture everything in the last day.
William Stacey [MVP]|||Hi Rob,
Thanks for your response, it is working fine. But i get the inputs only in
date format('10/01/2005'), So i want to concatenate the timestamp each time.
I have one method,
"select * from table_name where
convert(datetime,convert(varchar,column_
name) ) between '10/01/2005' and
'10/31/2005'
it is working fine.
Can you tell me it is efficient one. Please advise me.
rgds,
Soura
"Rob" wrote:

> Soura,
> '10/31/2005' assumes 10/31/2005 at midnight. Any records with a time of
> after midnight will not be included in the results.
> Try:
> select *
> from tablename
> where columnname between '10/01/2005' and '10/31/2005 23:59:59'
> Rob
> SouRa wrote:
>|||Hi William ,
Thanks for your response, it is working fine. But i get the inputs only in
date format('10/01/2005'), So i want to concatenate the timestamp each time.
I have one method,
"select * from table_name where
convert(datetime,convert(varchar,column_
name) ) between '10/01/2005' and
'10/31/2005'
it is working fine.
Can you tell me it is efficient one. Please advise me.
rgds,
Soura
"William Stacey [MVP]" wrote:

> or between '10/01/2005' and '10/31/2005 23:59:59.997'
> to capture everything in the last day.
> --
> William Stacey [MVP]
>
>|||Did you read my article?

> "select * from table_name where
> convert(datetime,convert(varchar,column_
name) ) between '10/01/2005' and
> '10/31/2005'
Above will negate the usage of indexes on the column. Can potentially be dis
astrous for performance.
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/
Blog: http://solidqualitylearning.com/blogs/tibor/
"SouRa" <SouRa@.discussions.microsoft.com> wrote in message
news:CD781D5B-4FF2-49B5-B673-A47EC0A60E7E@.microsoft.com...[vbcol=seagreen]
> Hi Rob,
> Thanks for your response, it is working fine. But i get the inputs only in
> date format('10/01/2005'), So i want to concatenate the timestamp each tim
e.
> I have one method,
> "select * from table_name where
> convert(datetime,convert(varchar,column_
name) ) between '10/01/2005' and
> '10/31/2005'
> it is working fine.
> Can you tell me it is efficient one. Please advise me.
> rgds,
> Soura
> "Rob" wrote:
>

Better proformance using join or sub-query?

All,
I am using a trigger to keep a "transaction date" column up-to-date with
the datetime the record was lasted inserted/updated. My question is which
SQL statement would provide better performance:
Update tablename set transdate = getdate() where primarykey in (select
primarykey from inserted)
or
update tablename set transdate = getdate
from tablename, inserted
where tablename.primarykey = inserted.primarykey
Thanks,
James K.I recommend
update tablename set transdate = getdate
from tablename, inserted
where tablename.primarykey = inserted.primarykey
Roji. P. Thomas
Net Asset Management
https://www.netassetmanagement.com
"-=JLK=-" <jknowlto-nospam@.dtic.mil> wrote in message
news:eowog0nGFHA.2740@.TK2MSFTNGP12.phx.gbl...
> All,
> I am using a trigger to keep a "transaction date" column up-to-date
> with the datetime the record was lasted inserted/updated. My question is
> which SQL statement would provide better performance:
> Update tablename set transdate = getdate() where primarykey in (select
> primarykey from inserted)
> or
> update tablename set transdate = getdate
> from tablename, inserted
> where tablename.primarykey = inserted.primarykey
> Thanks,
> James K.
>|||I think the second one
Madhivanan|||JKL
I'd go with the first one. The probelm with the second one is that under
some conditions you can get a different ( wrong) output
David Portas has written some script/test about this
CREATE TABLE Countries
(countryname VARCHAR(20) NOT NULL PRIMARY KEY,
capitalcity VARCHAR(20));
CREATE TABLE Cities
(cityname VARCHAR(20) NOT NULL,
countryname VARCHAR(20) NOT NULL
REFERENCES Countries (countryname),
CONSTRAINT PK_Cities
PRIMARY KEY (cityname, countryname));
INSERT INTO Countries (countryname, capitalcity) VALUES ('USA', NULL);
INSERT INTO Countries (countryname, capitalcity) VALUES ('UK', NULL);
INSERT INTO Cities VALUES ('Washington', 'USA');
INSERT INTO Cities VALUES ('London', 'UK');
INSERT INTO Cities VALUES ('Manchester', 'UK');
The MS-syntax makes it all too easy for the developer to slip-up by
writing ambiguous UPDATE...FROM statements where the JOIN criteria is
not unique on the right side of the join.
Try these two identical UPDATE statements with a small change to the
primary key in between.
UPDATE Countries
SET capitalcity = cityname
FROM Countries JOIN Cities /* evil UPDATE... FROM syntax */
ON Countries.countryname = Cities.countryname;
SELECT * FROM Countries;
ALTER TABLE Cities DROP CONSTRAINT PK_Cities;
ALTER TABLE Cities ADD CONSTRAINT PK_Cities PRIMARY KEY (countryname,
cityname);
UPDATE Countries
SET capitalcity = cityname
FROM Countries JOIN Cities /* don't do this! */
ON Countries.countryname = Cities.countryname;
SELECT * FROM Countries;
You get this from the first SELECT statement:
countryname capitalcity
-- --
UK London
USA Washington
and this from the second:
countryname capitalcity
-- --
UK Manchester
USA Washington
"-=JLK=-" <jknowlto-nospam@.dtic.mil> wrote in message
news:eowog0nGFHA.2740@.TK2MSFTNGP12.phx.gbl...
> All,
> I am using a trigger to keep a "transaction date" column up-to-date
with
> the datetime the record was lasted inserted/updated. My question is which
> SQL statement would provide better performance:
> Update tablename set transdate = getdate() where primarykey in (select
> primarykey from inserted)
> or
> update tablename set transdate = getdate
> from tablename, inserted
> where tablename.primarykey = inserted.primarykey
> Thanks,
> James K.
>|||Uri,
The original poster want to update the column the getDate().
I think, As long as you dont depend on the joined table for the
value to update, you are safe.
Roji. P. Thomas
Net Asset Management
https://www.netassetmanagement.com
"Uri Dimant" <urid@.iscar.co.il> wrote in message
news:Of9GdAoGFHA.2420@.TK2MSFTNGP14.phx.gbl...
> JKL
> I'd go with the first one. The probelm with the second one is that under
> some conditions you can get a different ( wrong) output
> David Portas has written some script/test about this
> CREATE TABLE Countries
> (countryname VARCHAR(20) NOT NULL PRIMARY KEY,
> capitalcity VARCHAR(20));
> CREATE TABLE Cities
> (cityname VARCHAR(20) NOT NULL,
> countryname VARCHAR(20) NOT NULL
> REFERENCES Countries (countryname),
> CONSTRAINT PK_Cities
> PRIMARY KEY (cityname, countryname));
> INSERT INTO Countries (countryname, capitalcity) VALUES ('USA', NULL);
> INSERT INTO Countries (countryname, capitalcity) VALUES ('UK', NULL);
> INSERT INTO Cities VALUES ('Washington', 'USA');
> INSERT INTO Cities VALUES ('London', 'UK');
> INSERT INTO Cities VALUES ('Manchester', 'UK');
> The MS-syntax makes it all too easy for the developer to slip-up by
> writing ambiguous UPDATE...FROM statements where the JOIN criteria is
> not unique on the right side of the join.
> Try these two identical UPDATE statements with a small change to the
> primary key in between.
> UPDATE Countries
> SET capitalcity = cityname
> FROM Countries JOIN Cities /* evil UPDATE... FROM syntax */
> ON Countries.countryname = Cities.countryname;
> SELECT * FROM Countries;
> ALTER TABLE Cities DROP CONSTRAINT PK_Cities;
> ALTER TABLE Cities ADD CONSTRAINT PK_Cities PRIMARY KEY (countryname,
> cityname);
> UPDATE Countries
> SET capitalcity = cityname
> FROM Countries JOIN Cities /* don't do this! */
> ON Countries.countryname = Cities.countryname;
> SELECT * FROM Countries;
> You get this from the first SELECT statement:
> countryname capitalcity
> -- --
> UK London
> USA Washington
> and this from the second:
> countryname capitalcity
> -- --
> UK Manchester
> USA Washington
>
>
> "-=JLK=-" <jknowlto-nospam@.dtic.mil> wrote in message
> news:eowog0nGFHA.2740@.TK2MSFTNGP12.phx.gbl...
> with
>|||On Fri, 25 Feb 2005 13:00:35 +0530, avnrao wrote:

>Umi, can you please explain the rationale behind it.
Hi Av.,
Mind if I do instead of Uri?
The ANSI syntax and the proprietary UPDATE FROM syntax behave only the
same if for each row in the updated table that satisfies the WHERE
clause, exactly one row in the other table matches the join criteria.
If it's possible that no rows are matched, the ANSI syntax will set the
column to NULL, unless excluded from the update in the WHERE clause. The
UPDATE FROM syntax will not update this row: since it doesn't satisfy
the join criteria, it won't be updated even if it does meet the
requirements of the WHERE clause.
(Note: this difference can be circumvened by using outer join instead of
inner join to make the joined update behave exactly as the ANSI version)
The biggest difference is when one row to be updated can be matched
against more than one row in the source table. This is what's happening
in David's script, as posted by Uri.
In the ANSI version, if the subquery in the SET clause returns more than
one row, you'll get an error message. That ensures that you will revisit
the query and change it so that it will always return exactly one row -
the row that you want it to return.
The UPDATE FROM syntax won't throw an error if a row in the table to be
updated matches against multiple rows from the source. Instead, SQL
Server will just pick one of these rows and use that one to determine
the new values in your table. Or rather, in case you want the full
details, it will update the same row over and over again with each
matching row - and since the result of all but the last change is
overwritten, the net effect is that only the results from the row
processed last will stick.
The above explains why the result of an UPDATE FROM where one row to be
updated matches more than one row from the source is completely
unpredictable: the result will be from the last row processed, but there
is no way to predict the order of evaluation SQL Server will choose for
your query. David's example shows how an index can change the order, but
there are other possibilities: parallellism, available memory, workload,
and the possibility to "piggy-back" another query are just some examples
of how the order of evaluation (and hence the result of the update) may
change between successive execution, even if no schema or data has been
changed!
I hope this helps.
Best, Hugo
--
(Remove _NO_ and _SPAM_ to get my e-mail address)