I have two tables whose results I am trying to combine.
Create table dbo.streetaddr1(HomeID INT,Address varchar(200));
INSERT INTO dbo.streetaddr1 VALUES(1, '656 ave.');
INSERT INTO dbo.streetaddr1 VALUES(2,'B-6 ');
INSERT INTO dbo.streetaddr1 VALUES(3,'13 villa ');
Create table dbo.streetaddr2(HomeID INT,Address varchar(200));
INSERT INTO dbo.streetaddr2 VALUES(1, '656 ave.');
INSERT INTO dbo.streetaddr2 VALUES(2,'B-6 6th avene');
INSERT INTO dbo.streetaddr2 VALUES(4,'25 Main street');
INSERT INTO dbo.streetaddr2 VALUES(5,'135 Elm St ');
If a HomeID exists in dbo.streetaddr1, we pick Address from that even though it also exists in dbo.streetaddr2 we do not
pick it. If a HomeID does not exists in dbo.streetaddr1 then we pick those addresses from dbo.streetaddr2
Expected output table is as below:
Create table dbo.outputtable(HomeID INT,Address varchar(200));
INSERT INTO dbo.outputtable VALUES(1, '656 ave.');
INSERT INTO dbo.outputtable VALUES(2,'B-6 ');
INSERT INTO dbo.outputtable VALUES(3,'13 villa ');
INSERT INTO dbo.outputtable VALUES(4,'25 Main street');
INSERT INTO dbo.outputtable VALUES(5,'135 Elm St ');
How can I do that?
thanks
Rs
Try this
SELECT COALESCE(S1.HOMEID,S2.HOMEID) AS HOMEID,
COALESCE(S1.ADDRESS,S2.ADDRESS) AS ADDRESS
FROM streetaddr1 S1
full join streetaddr2 s2 on s1.HomeId = s2.HomeId
Related
I have two tables in MS SQL:
CREATE TABLE Table1 (ID INT IDENTITY(1,1) NOT NULL, TEXTVal VARCHAR(100), Table2Id int)
insert into Table1 (TEXTVal) values('aaa');
insert into Table1 (TEXTVal) values('bbb'); insert into Table1 (TEXTVal) values('ccc');
CREATE TABLE Table2 (ID INT IDENTITY(1,1) NOT NULL, TEXTVal VARCHAR(100), Table2Id int)
Id are identity columns. I want to copy TEXTVal values from Table1 to Table2:
INSERT INTO Table2 (TEXTVal)
SELECT TEXTVal FROM Table1
where TEXTVal <> 'ccc'
and after that update column Table2Id in Table1 with appropriate values of Id from Table2. I can do this with cursor and SCOPE_IDENTITY().
I am just wondering, is there a way to do it without cursor in T-SQL?
As Jeroen stated in comments, you'll want to use OUTPUT. In the following example if you don't have an AdventureWorks database, just use a test database. You should be able to copy/paste this and just run it to see it in action!
USE AdventureWorks;
GO
----Creating the table which will store permanent table
CREATE TABLE TestTable (ID INT, TEXTVal VARCHAR(100))
----Creating temp table to store ovalues of OUTPUT clause
DECLARE #TmpTable TABLE (ID_New INT, TEXTVal_New VARCHAR(100),ID_Old INT, TEXTVal_Old VARCHAR(100))
----Insert values in real table
INSERT TestTable (ID, TEXTVal)
VALUES (1,'FirstVal')
INSERT TestTable (ID, TEXTVal)
VALUES (2,'SecondVal')
----Update the table and insert values in temp table using Output clause
UPDATE TestTable
SET TEXTVal = 'NewValue'
OUTPUT Inserted.ID, Inserted.TEXTVal, Deleted.ID, Deleted.TEXTVal INTO #TmpTable
WHERE ID IN (1,2)
----Check the values in the temp table and real table
----The values in both the tables will be same
SELECT * FROM #TmpTable
SELECT * FROM TestTable
----Clean up time
DROP TABLE TestTable
GO
ResultSet:
TmpTable:
ID_New TextVal_New ID_Old TextVal_Old
——————— ——————— ——————— ———————
1 NewValue 1 FirstVal
2 NewValue 2 SecondVal
Original Table:
ID TextVal
——————— ———————
1 NewValue
2 NewValue
As you can see it is possible to capture new values, and the values you are updating. In this example I'm just stuffing them into a table variable but you could do whatever you'd like with them. :)
Just for simplicity suppose I have two tables
user table (id, email)
user log table (id, date)
whatever id gets inserted in user table, same id should be inserted in user_log table also else transaction should fail.
How can I do this
BEGIN TRANSACTION
INSERT into user(id, email) OUTPUT Inserted.id (1, 'a#x.com', 'x'), (2, 'b#x.com', 'y')
// I also want to be able to do
INSERT into user_log(id, date) values(1, date), (2, date)
COMMIT TRANSACTION
You can insert the output directly into the user_log table:
BEGIN TRANSACTION
INSERT INTO [User] (ID, Email)
OUTPUT inserted.id, CURRENT_TIMESTAMP INTO user_log(id, date)
VALUES (1, 'a#x.com'), (2, 'b#x.com');
COMMIT TRANSACTION
Example on SQL Fiddle
If you need to return the ids you can just add a second OUTPUT clause:
BEGIN TRANSACTION
INSERT INTO [User] (ID, Email)
OUTPUT inserted.id, CURRENT_TIMESTAMP INTO user_log(id, date)
OUTPUT inserted.id
VALUES (1, 'a#x.com'), (2, 'b#x.com');
COMMIT TRANSACTION
Method 1 - "Double Insert" using OUTPUT
Pros: single statement, no hidden triggers (method 2).
Cons: only works in this statement i.e. doesn't capture all insert events
INSERT INTO dbo.users (id)
OUTPUT inserted.id
INTO user_log (id)
VALUES (9)
, (3)
, (7)
;
Method 2 - Trigger
Pros: Captures all insert events
Cons: Triggers are "hidden" mechanisms
CREATE TRIGGER user_log_after_insert
ON dbo.users
AFTER INSERT
AS
BEGIN
INSERT INTO dbo.user_log (id)
SELECT id
FROM inserted
;
END
;
Method 3 - Temp Table
Included for completeness for when using older versions of SQL Server that don't support method 1
CREATE TABLE #temp (
id int
);
INSERT INTO #temp (id) VALUES (9);
INSERT INTO #temp (id) VALUES (3);
INSERT INTO #temp (id) VALUES (7);
BEGIN TRAN
INSERT INTO dbo.users (id)
SELECT id
FROM #temp
;
INSERT INTO dbo.user_log (id)
SELECT id
FROM #temp
;
COMMIT TRAN
when this query is executed
DECLARE #Temp TABLE (ID INT IDENTITY,Name VARCHAR(50),ID2 INT NULL)
INSERT INTO #Temp ([Name]) VALUES ('Ali')
UPDATE #Temp SET ID2= (SELECT SCOPE_IDENTITY()) WHERE [ID]=(SELECT SCOPE_IDENTITY())
INSERT INTO #Temp ([Name]) VALUES ('Veli')
UPDATE #Temp SET ID2= (SELECT SCOPE_IDENTITY()) WHERE [ID]=(SELECT SCOPE_IDENTITY())
SELECT * FROM #Temp
We can get this table
ID-NAME-ID2
1 - Ali - 1
2 - Veli - 2
is there a way to do this in one insert query ( Assigning inserted id to another column without using idendity property in that column) ?
thanks a lot.
You want to make it a computed column like below
create TABLE Temp(ID INT IDENTITY,Name
VARCHAR(50),
ID2 AS ID PERSISTED);
Then insert rows ... your ID values will be persisted in ID2 column
INSERT INTO Temp ([Name])
VALUES ('Ali');
INSERT INTO Temp ([Name])
VALUES ('Veli');
INSERT INTO Temp ([Name])
VALUES ('Neli');
Which will results in
See a demo fiddle here http://sqlfiddle.com/#!3/59fca/1
EDIT:
If you can't change your table structure then the only way insert ID value to ID2 column is the way you are currently doing it cause in same insert statement the identity value is still not available and so it will be null.
I need to write procedure Textprocedure (Table_txt varchar(200)) that scans data from table My_table
For ex: I have table
My_table (Id int, Name varchar(200))
I need result of procedure execution like output text (script) like
DELETE FROM My_table
INSERT INTO My_table (Id, Name) values (1, 'Tropico')
INSERT INTO My_table (Id, Name) values (2, 'Bus')
INSERT INTO My_table (Id, Name) values (4, 'Africa')
INSERT INTO My_table (Id, Name) values (8, 'Arrival')
Can I do it with procedure? I do
CREATE TABLE My_table (Id int, Name varchar(200))
DELETE FROM My_table
INSERT INTO My_table (Id, Name) values (1, 'Tropico')
INSERT INTO My_table (Id, Name) values (2, 'Bus')
INSERT INTO My_table (Id, Name) values (4, 'Africa')
INSERT INTO My_table (Id, Name) values (8, 'Arrival')
ALTER PROCEDURE Textprocedure (#Table_txt varchar(200))
AS
BEGIN
DECLARE #Id1 NVARCHAR(40)
DECLARE #Result NVARCHAR(4000)
SET #Result = ''
SELECT #Result = 'INSERT INTO '+ CAST(#Table_txt AS NVARCHAR(250)) + --#Result
+'() values ' + CAST([name] AS NVARCHAR(250)) + ' ' FROM My_table --where Id<5
PRINT (#Result)
END
GO
EXEC Textprocedure My_table
My output: INSERT INTO My_table() values Arrival
But I need result in many rows. Can I do cycle? And I need print table params like id, name? But how can I pick them?
Check this to generate insert statements:
https://stackoverflow.com/a/982576/590741
http://vyaskn.tripod.com/code/generate_inserts.txt
You can use dynamic sql with parameters then print or return the result.
I have two tables with foreign key constraint on TableB on TablesAs KeyA column. I was doing manual inserts till now as they were only few rows to be added. Now i need to do a bulk insert, so my question if i insert multiple rows in TableA how can i get all those identity values and insert them into TableB along with other column values. Please see the script below.
INSERT INTO Tablea
([KeyA]
,[Value] )
SELECT 4 ,'StateA'
UNION ALL
SELECT 5 ,'StateB'
UNION ALL
SELECT 6 ,'StateC'
INSERT INTO Tableb
([KeyB]
,[fKeyA] //Get value from the inserted row from TableA
,[Desc])
SELECT 1 ,4,'Value1'
UNION ALL
SELECT 2 ,5,'Value2'
UNION ALL
SELECT 3 ,6, 'Value3'
You can use the OUTPUT clause of INSERT to do this. Here is an example:
CREATE TABLE #temp (id [int] IDENTITY (1, 1) PRIMARY KEY CLUSTERED, Val int)
CREATE TABLE #new (id [int], val int)
INSERT INTO #temp (val) OUTPUT inserted.id, inserted.val INTO #new VALUES (5), (6), (7)
SELECT id, val FROM #new
DROP TABLE #new
DROP TABLE #temp
The result set returned includes the inserted IDENTITY values.
Scope identity sometimes returns incorrect value. See the use of OUTPUT in the workarounds section.