Unique entries over to tables in database - sql-server

I have a problem where I need to check that two columns in each table in a database are unique.
We have the database with barcode entries called uid and rid.
Table 1: T1.uid
And
Table 2: T2.rid
No barcodes in the two table columns must be the same.
How can we ensure that.
If a insertion of a barcode into table T1.uid matches an entry in
T2.rid we want to throw an error.
The tables are cleaned up and is in a consistent state where the entries in
T1.uid and T2.rid are unique over both table columns.
It is not possible to insert NULL values in the tables respective uid and tid column(T1.uid and T2.rid)
It is not possible to create a new table for all barcodes.
Because we don't have full control of the database server.
EDIT 19-02-2015
This solution cannot work for us, because we cannot make a new table
to keep track of the unique names(see table illustration).
We want to have a constraint over two columns in different tables without changing the schema.
Per the illustration we want to make it impossible for john to exist in
T2 because he already exists in table T1. So an error must be "thrown"
when we try to insert John in T2.Name.
The reason is that we have different suppliers that inserts into these tables
in different ways, if we change the schema layout, all suppliers would
need to change their database queries. The total work is just to much,
if we force every suppplier to make changes.
So we need something unobtrusive, that doesnt require the suppliers to change
their code.
A example could be that T1.Name is unique and do not accept NULL values.
If we try insert an existing name, like "Alan", then an exception will occur
because the column has unique values.
But we want to check for uniqueness in T2.Name at the same time.
The new inserted value should be unique over the two tables.

Maybe something like this:
SELECT uid FROM Table1
Where Exists (
SELECT rid FROM Table2
WHERE Table1.uid = rid )
This will show all rows from Table1 where their column uid has an equivalent in column rid of Table2.

The condition before the insertion happens could look like below. #Idis the id you need to insert the data for.
DECLARE #allowed INT;
SELECT #allowed = COUNT(*)
FROM
(
SELECT T1.uid FROM T1 WHERE T1.uid = #Id
UNION ALL
SELECT T2.rid FROM T2 WHERE T2.rid = #id
)
WHERE
#id IS NOT NULL;
IF #allowed = 0
BEGIN
---- insert allowed
SELECT 0;
END

Thanks to all who answered.
I have solved the problem. A trigger is added to the database
everytime an insert or update procedure is executed, we catch it
check that the value(s) to be inserted doens't exist in the columns of the two
tables. if that check is succesfull we exceute the original query.
Otherwise we rollback the query.
http://www.codeproject.com/Articles/25600/Triggers-SQL-Server
Instead Of Triggers

Related

SQL Change in one table automatically change the other table

I am new to Database and in SQL also. I have two tables t1 and t2. There is a "name" column in t1 and t2 tables. Here t1. name will be given by me, but I want that t2. name automatically change on the basis of t1. id=t2. id please help me by giving SQL query for it. Also tells me "is, stored procedures or triggers required for this?" If yes, then how I will use them? Thanks in advance..... :-)
CREATE TRIGGER [dbo].[trg_Table2]
ON [dbo].[table1] AFTER UPDATE
AS
BEGIN
IF UPDATE (name)
BEGIN
INSERT INTO table2 (name)
SELECT d.name FROM DELETED d
END
END
I provided you an idea. Use it for updating the record. Here 'Deleted' table is the one where the data changed in table1 which can be used to store that previous data into other table that you want. I inserted the data, you update it now.
Sorry, I just saw it, you want the current data then use the 'INSERTED' table just like the 'DELETED'.

how to update table(new_DB) from old table(old_DB)

What I have:
1 table(table is in both DB's)
2 databases(currently used + archived from last year(old))
"ID" is the primary key for the table.
my issue:
archived database table has rows in it that is not present in the currently used database table. Can anyone tell me how I go about updating the currently used database table from the old database table(i.e. insert * unique rows from old database table into new database table)
It sounds simple enough but wanted some advice before proceeding as I DO NOT want duplicate rows, I just want to throw the rows in the old table(that IS NOT present in the currently used database table) into the new one(copy only is fine).
I hope I explained clearly enough.
Insert rows from the new table only if row with same id not exists in old table:
insert into old_table select * from new_table nt
where not exists (select 1 from old_table
where id = nt.id)
(Specifying columns, both inserted and selected, is nice - but I'm lazy here...)
You can usually address tables from other databases by prefixing the database name: new_db.foo_table or old_db.foo_table. This way you can look for rows in the old table that have no duplicates in the new table:
select *
from old_db.foo_table as old_foo
where not exists (
select 1
from new_db.foo_table as new_foo
where new_foo.key_field = old_foo.key_field
-- add more comparisons as needed
);
Then you can use the insert into new_db.foo_table select ... syntax to put the records into the new table.
Use LEFT JOIN filtering NULLs in target table. I think it will be faster
INSERT INTO NEW_TABLE
SELECT ot.* FROM OLD_TABLE ot
LEFT JOIN NEW_TABLE nt on ot.ID = nt.ID
WHERE nt.ID IS NULL

How to use INSERT SELECT?

I have a table's structure:
[Subjects]:
id int Identity Specification yes
Deleted bit
[Juridical]:
id int
Name varchar
typeid int
[Individual]:
id int
Name varchar
Juridical and Individual it's a children classes of Subjects class. So it's mean that same rows in tables Individual and Subjects have a same id.
Now I have a table:
[MyTable]:
typeid varchar
Name varchar
And I want to select data from this table and insert it into my table structure. But I don't know what to do. I tried to use OUTPUT:
INSERT INTO [Individual](Name)
OUTPUT false
INTO [Subjects].[Deleted]
SELECT [MyTable].[Name] as Name
FROM [MyTable]
WHERE [MyTable].[type] = 'Indv'
But the syntax is not correct.
Just use:
INSERT INTO Individual(Name)
SELECT [MyTable].[Name] as Name
FROM [MyTable]
WHERE [MyTable].[type] = 'Indv'
and
INSERT INTO Subjects(Deleted)
SELECT [MyTable].[Name] as Name
FROM [MyTable]
WHERE [MyTable].[type] = 'Indv'
You can't insert in a single query in two tables, you need two separate queries for that. For that reason I split your initial query into two INSERT statements, to add records to both your Individual and Subjects table.
Just as #marc_s said, you must select the exact number of columns in your SELECT statement with the number of columns you want to insert data into your tables.
Other than these two constraints, which are both related to syntax, you are fully allowed to do any filtering in the SELECT part or make any complex logic as you would do in a normal SELECT query.
You need to use this syntax:
INSERT INTO [Individual] (Name)
SELECT [MyTable].[Name]
FROM [MyTable]
WHERE [MyTable].[type] = 'Indv'
You should define the list of column to insert into in the INSERT INTO line, and then you must have a SELECT that returns exactly that many columns as you need (and the column types need to match, too)

SQL Script add records with identity FK

I am trying to create an SQL script to insert a new row and use that row's identity column as an FK when inserting into another table.
This is what I use for a one-to-one relationship:
INSERT INTO userTable(name) VALUES(N'admin')
INSERT INTO adminsTable(userId,permissions) SELECT userId,255 FROM userTable WHERE name=N'admin'
But now I also have a one-to-many relationship, and I asked myself whether I can use less SELECT queries than this:
INSERT INTO bonusCodeTypes(name) VALUES(N'1500 pages')
INSERT INTO bonusCodeInstances(codeType,codeNo,isRedeemed) SELECT name,N'123456',0 FROM bonusCodeTypes WHERE name=N'1500 pages'
INSERT INTO bonusCodeInstances(codeType,codeNo,isRedeemed) SELECT name,N'012345',0 FROM bonusCodeTypes WHERE name=N'1500 pages'
I could also use sth like this:
INSERT INTO bonusCodeInstances(codeType,codeNo,isRedeemed)
SELECT name,bonusCode,0 FROM bonusCodeTypes JOIN
(SELECT N'123456' AS bonusCode UNION SELECT N'012345' AS bonusCode)
WHERE name=N'1500 pages'
but this is also a very complicated way of inserting all the codes, I don't know whether it is even faster.
So, is there a possibility to use a variable inside SQL statements? Like
var lastinsertID = INSERT INTO bonusCodeTypes(name) OUTPUT inserted.id VALUES(N'300 pages')
INSERT INTO bonusCodeInstances(codeType,codeNo,isRedeemed) VALUES(lastinsertID,N'123456',0)
OUTPUT can only insert into a table. If you're only inserting a single record, it's much more convenient to use SCOPE_IDENTITY(), which holds the value of the most recently inserted identity value. If you need a range of values, one technique is to OUTPUT all the identity values into a temp table or table variable along with the business keys, and join on that -- but provided the table you are inserting into has an index on those keys (and why shouldn't it) this buys you nothing over simply joining the base table in a transaction, other than lots more I/O.
So, in your example:
INSERT INTO bonusCodeTypes(name) VALUES(N'300 pages');
DECLARE #lastInsertID INT = SCOPE_IDENTITY();
INSERT INTO bonusCodeInstances(codeType,codeNo,isRedeemed) VALUES (#lastInsertID, N'123456',0);
SELECT #lastInsertID AS id; -- if you want to return the value to the client, as OUTPUT implies
Instead of VALUES, you can of course join on a table instead, provided you need the same #lastInsertID value everywhere.
As to your original question, yes, you can also assign variables from statements -- but not with OUTPUT. However, SELECT #x = TOP(1) something FROM table is perfectly OK.

SQL Server - Select inserted rows in a table, inside THE SAME transaction

I need confirmation for one "tricky" question.
I am in a transaction, in which i insert some rows in a table.
After that, querying the same table, and based on the results, i insert in another table.
My question is: Will the inserted rows in the first table be visible when inserting in the second table? (I need the inserted rows to be visible).
My first Insert Is :
INSERT INTO BioUsers Select NewId(),A.BadgeNr,GetDate(),A.PersNr
FROM (
SELECT CB.Persnr,C.BadgeNr FROM CurBioDistribution CB
INNER JOIN CUR C ON C.PersNr = CB.PersNr
WHERE
CB.[Type] = 1
AND CB.GroupNr = #Nr
AND CB.PersNr IN (SELECT PersNr FROM CurBioDistribution WHERE GroupNr = #Nr)
EXCEPT (SELECT PersNr, BadgeId as BadgeNr FROM BioUsers)
) A
I want To insert all the BioUserID's in the first table in another table, which contains the field BioUserID, but only if they are not already in it. So when select from the first one, i want to get the inserted rows too.
PS: I searched for this problem, but i could only find answers about this issue when multiple transaction (from different clients) are involved.
If both inserts are in the same transaction, then yes.
If not then you are in what you described as a multi-user scenario. Multi user is infact misleading, multi transaction would be more correct.

Resources