|
Let me clarify:
Let's say I have a table called address with fields: id, street, streetnumber, busnumber, placeid.
id is the primary key of that table.
Now I insert a row in that table with data in the following fields: street, streetnumber, busnumber, placeid. id is generated by a sequence, but that part doesn't matter. The unique constraint is about those 4 fields.
Suppose I want to insert 2 people who live at the same address, but while this is unknown to me.
Instead of getting a unique constraint warning, I would like to get the id of the record that matches the data I'm trying to insert. I've thought about doing it in the same stored procedure, but I don't know that much about errorhandling inside a stored procedure. I am trying to avoid to having to handle it in my application.
Could you help me out with that?
|
|
|
|
|
Nico Haegens wrote: I want to insert 2 people who live at the same address
Get rid of the unique constraint if it doesn't support the application properly.
Why not check the table first, before trying to insert the record?
You'll never get very far if all you do is follow instructions.
|
|
|
|
|
My point is to link the two people to the same address, instead of making 2 duplicate addresses.
Checking the table every time I make an insert, makes the process slower than if I were to do it after, cause then I only need to check the database twice when the exception occurs instead of twice every time I do the insert.
|
|
|
|
|
We did that at one place I worked. We had a table of addresses and checked for the address each time. It wasn't slow. You could probably make a hash to speed it up.
You'll never get very far if all you do is follow instructions.
|
|
|
|
|
Nico Haegens wrote: I would like to know how to return the primary key(the column is always called id) ...All my insert statements are in stored procedures
Write a lot of code - duplicating every constraint that you have. In every stored procedure that does an insert. So if you have a unique name constraint in your customer table then your insert for the customer first checks to see that the name is unique. If it isn't then it throws an error. If it is then it proceeds to doing the actual insert. Course you might want to create a table transaction as well since someone could insert a different row with the name as well.
Naturally this isn't efficient. Nor performant. Applications should be coded to prevent this in the first place rather than relying on the database to provide error notification (versus error prevention.)
|
|
|
|
|
Here is one of the situations I have:
I insert a person and an address the person provided. Addresses are in a seperate table.
So brief table layout:
person table: firstname, lastname, addressid
address table: id, street, streetnbr, busnbr, placeid. There is a unique constraint on the combination of all 4 fields that aren't the id.
Person A comes along to one of my client's employees and gives his info and a certain address.
Person B comes along to another one of my client's employees, gives his info and the same address as person A.
here is what currently happens in my app:
app receives sqlexception with the error saying there was a unique constraint problem and I respond to it in app by doing a sql statement that selects the record that matches the unique address.
Here is what I would like to happen:
stored procedure for Address tries to insert the address, finds out it already exists(throws exception in db) cause of the unique constraint and instead of supplying the id of the newly inserted record, it supplies the id of the existing record. Imo, this is far faster than what I have now, as the problem is handled before it leaves the stored procedure.
Problem is, I know nothing about error handling in SQL Server.
Here is my current sql statement for my SP:
ALTER procedure [dbo].[AddressInsert](@street varchar(255), @streetnumber varchar(255), @busnumber varchar(255), @placeid bigint, @newid bigint output) as begin
set @newid = next value for dbo.baseidseq
insert into [Address](baseid, street, streetnumber, busnumber, placeid) values(@newid, @street, @streetnumber, @busnumber, @placeid) end
What statement(s) do I add to return the id of the row that matches the parameters provided?
I assume I have to add something like select * from address where street = @street, etc. But what else?
|
|
|
|
|
Hi Nico
Sorry that this is not an answer, but more out of curiosity..
Lets say a man joins the company.
He gets an address ID.
His wife who lives at the same address joins the company.
With your app, you want to assign the same address ID to his wife.
They get divorced.
The man moves to another address, and tells the company his new address.
You update that address ID with the new address and then his wife will have moved back in with him since they share and address ID?
|
|
|
|
|
Here, in the real world, there's at least 5 families living at my address
--edit
They moved out when I moved in, obviously.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Not a VW bug I hope. 
|
|
|
|
|
Nico Haegens wrote: Person A comes along to one of my client's employees and gives his info and a certain address.
Person B comes along to another one of my client's employees, gives his info and the same address as person A.
here is what currently happens in my app:
What you have described is a hypothetical implementation scenario.
However what is the exact business case where this happens? Not what might happen but what does the actual people of this company using the application do?
Nico Haegens wrote: Problem is,
You don't have a problem until there is a business case.
For example given your description a 'customer' could in fact have the very same address as a different 'customer' and your current implementation would prevent you from entering it (regardless of why.) That can happen because a person might be legally incorporated as different companies yet work out of the same office (one person after all.) But as a legal entity the address in not in fact the 'same' despite being the same physical location.
|
|
|
|
|
Welcome to the "address" can of worms, there is another relating to phone numbers and names (marry/divorce) and surname/first name designation (try working in Asia).
The technical answer to your problem is that you MUST include a search for existing address in your insert procedure.
Defining the business case is going to drive you nuts, toss it back to the business/BA, their job is to tell you what you want. It can be entertaining watching the reaction when you start asking some of the questions you have received here.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Figured it out myself:
use try catch clause and check for error_number()=2627
declare @newid bigint = next value for dbo.baseidseq
BEGIN TRANSACTION
begin try
insert into [Address](id, street, streetnumber, busnumber, placeid)
values(@newid, @street, @streetnumber, @busnumber, @placeid)
end try
begin catch
if ERROR_NUMBER()=2627
begin
set @newid = (select baseid from [Address]
where street like @street and streetnumber like @streetnumber and busnumber like @busnumber and placeid=@placeid)
end
else
rollback transaction
END catch
if @@TRANCOUNT>0
COMMIT TRANSACTION
select @newid
|
|
|
|
|
Do some research into the MERGE keyword, it caters for this requirement (I think as I have not used it).
Programming by error - one of my pet peeves, if this turned up in any of our code reviews the dev would be castigated.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Hello..i have a question about SQL Statements
In my database, i have a data about datetime. The example as shown below:
2014-03-25 17:57:34.177
2014-03-25 18:01:25.280
2014-03-25 18:01:28.240
2014-03-25 18:01:33.207
This is just a few example but in my database the data is more than this.So how if i want to display the data from 30 minutes ago? what is the sql statement should I use?
|
|
|
|
|
SELECT * FROM tablename WHERE datefield > DateADD(mi, -30, Current_TimeStamp)
|
|
|
|
|
tq and if i want to show from 1 hours is it like this SELECT * FROM tablename WHERE datefield > DateADD(mi, -60, Current_TimeStamp)?
|
|
|
|
|
|
tqvm for helping me 
|
|
|
|
|
Hye peter, this code seems did'nt work..when I execute this SQL to the database directly, it will show no result 
|
|
|
|
|
Seeing is believing. try this: http://sqlfiddle.com/#!3/1fa93/13028
|
|
|
|
|
Hi
I need to multiply two columns (float) each of which can have a max of 4 decimal places and round the result to 3 decimal places.
It seems the ROUND(val,decimal_places) uses bankers rounding? (SQL Sever 2008R2) - Although I have read it uses Symmetric Arithmetic Rounding?
Doing the same calculation in Excel gives me the result I need, but Excel uses normal Arithmetic rounding.
How can I do a query to use arithmetic rounding (like Excel)
Examples of the errors:
Price Qty Val ExcelRound SQLRound
7.5169 745 5600.0905 5600.091 5600.090
4.3465 463 2012.4295 2012.430 2012.429
1.6401 125 205.0125 205.013 205.012
0.0395 369 14.5755 14.576 14.575
5.2349 955 4999.3295 4999.330 4999.329
9.0285 141 1273.0185 1273.019 1273.018
9.0899 645 5862.9855 5862.986 5862.985
3.6167 215 777.5905 777.591 777.590
3.1145 135 420.4575 420.458 420.457
7.4115 105 778.2075 778.208 778.207
7.8675 313 2462.5275 2462.528 2462.527
8.8405 227 2006.7935 2006.794 2006.793
5.4269 55 298.4795 298.480 298.479
1.8833 445 838.0685 838.069 838.068
9.7349 655 6376.3595 6376.360 6376.359
8.6487 365 3156.7755 3156.776 3156.775
1.9033 125 237.9125 237.913 237.912
4.8197 545 2626.7365 2626.737 2626.736
PS: how do you post a table with nicely formatted columns?
modified 9-May-14 17:33pm.
|
|
|
|
|
I think the general consensus is that it makes more sense to do that kind of formatting in your report, rather than in your database query.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Hi Richard
Thanks for your reply. In my case here, a customer was requesting a Purchase Order in pdf format, as well as Excel format. I was doing the rounding with a formula in Excel, but the formula did not always fill down to all the rows of the table which is why I decided to do the rounding in the query.
Also, quite often, in Winform apps, I pull a query into a DataTable, and set the DataTable as a DataGridView DataSource, in which case it seems more practical to do the rounding in the query as opposed to looping through the DataTable, and adding the rows with the rounded value to the DataGridView?
|
|
|
|
|
Hi,
The problem is not a ROUND function, but the precision of the FLOAT data type (Using decimal, float, and real Data[^]). You have at least a couple of options:
1. Use DECIMAL or NUMERIC instead of the FLOAT.
2. CAST to DECIMAL for the calculation.
Here's the demonstration for you (using your first example):
1. Select using ROUND.
SELECT ROUND((7.5169 * 745), 3) AS Result;
or
SELECT ROUND(5600.0905, 3) AS Result;
Result: 5600.0910
2. Using FLOAT variables.
DECLARE @a FLOAT, @b FLOAT, @c FLOAT;
SET @a = 7.5169;
SET @b = 745;
SET @c = @a * @b;
SELECT ROUND(@c, 3) AS Result;
Result: 5600.09
3. Using DECIMAL variables.
DECLARE @a DECIMAL(18, 4), @b DECIMAL(18, 4), @c DECIMAL(18, 4);
SET @a = 7.5169;
SET @b = 745;
SET @c = @a * @b;
SELECT ROUND(@c, 3) AS Result;
Result: 5600.0910
P.S. I am posting such data with the XML pre tag. Also, I am inserting (copying) TAB characters (if needed).
Best regards,
Andrius Leonavicius
|
|
|
|
|
Hi Andrius
Thanks So much.
Tested below with the same random sample of 300 values, and all agreed with the Excel Values!
select price
, qty
, price*qty as Val
, round(CONVERT(decimal(12,4),price)* CONVERT(decimal(12,4),qty),3) as RoundVal
from dbo.[round]
What mis-lead me into thinking the problem was with the type of rounding was that from my sample of 300 values, all the values that differed had a 5 in the 4th decimal place, and all the errors were not rounded as expected.
In the link you poseted:
Using float and real Data
The float and real data types are known as approximate data types. The behavior of float and real follows the IEEE 754 specification on approximate numeric data types.
...
The IEEE 754 specification provides four rounding modes: round to nearest, round up, round down, and round to zero. Microsoft SQL Server uses round up. All are accurate to the guaranteed precision but can result in slightly different floating-point values. Because the binary representation of a floating-point number may use one of many legal rounding schemes, it is impossible to reliably quantify a floating-point value.
Thanks for your help!
|
|
|
|
|