How to include a reference column with the OUTPUT in SQL [duplicate] - sql

This question already has answers here:
Is it possible to for SQL Output clause to return a column not being inserted?
(2 answers)
Closed 11 months ago.
I have a reference TableA with a single column called [SomeID]:
SomeID
ABC
DEF
GHI
KLM
I have TableB can be:
CREATE TABLE TableB([ID] BIGINT, [Name] NVARCHAR(50))
[ID] is the primary key and is auto-increment.
I want to create a new record in TableB for each record of TableA.
So we do this:
DECLARE #OuputTable TABLE([ID] BIGINT, [SomeID] NVARCHAR(50))
INSERT INTO TableB([Name])
OUTPUT INSERTED.[ID], 'Need Associated SomeID From TableA Here' INTO #OutputTable
SELECT 'ZZZZZZ' -- Edited this line to remove some possible confusion.
FROM TableA
SELECT *
FROM
#OuputTable
How would I be able to place the associated [SomeID] value for each of the created record in #OuputTable without using a loop?

You can try to use MERGE INTO which might allow you get source data value in OUTPUT
MERGE INTO TableB AS dest
USING TableA AS sou ON 1=0
WHEN NOT MATCHED
THEN INSERT ([Name])
VALUES (sou.[SomeID])
OUTPUT INSERTED.[ID], sou.SomeID
INTO #OutputTable (ID, SomeID);
sqlfiddle

Related

Is there a way to insert the same row values in a temp table? SQL Server

I have a temp table #t that has a column already called ID with about 75 values. I've inserted another column called status and I want all of the values in the 'status' column to equal "A". Is there a way I can do this without having to manually insert A for each row?
Would want it to look like this but for all 75 rows
|ID| |Status|
----------------
|24| | A |
Not sure if I understand your question correctly but you could do it with something like
update #t set Status = 'A'
You can do that by setting the default value for status column.
Create table #test(id int, status varchar(1) default 'A');
insert into #test (id) values (1),(2),(3);
Select * From #test;
id status
1 A
2 A
3 A
If your table is already created you may set the default value as the following:
ALTER TABLE #test ADD CONSTRAINT df_val DEFAULT 'A' FOR status;
See a demo from db<>fiddle.

While updating table1, how do I INSERT to table2 for every change in table 1?

I have a MEMBER table and NOTIFICATION table. On client side, I list all of the records in MEMBER table and there is a points column and this is shown as text input. So after I change the values for some members, I can click save button and this will update the records in my MEMBER table that's all right,
But the thing I want to accomplish is for every record whose points value has changed I want to INSERT a record in my notifications table.
I couldn't think of anything, how can I approach to this problem?
For notifications I made 3 tables by following the article in here
Use the output clause instead of trigger, they are bad.
You need the condition "where data_old <> data_new" case if you updated a column with the same value, SQL Server marked it as changed, even if the value hasn't changed
create table #example (id int identity(1,1) not null, data nvarchar(max));
insert into #example (data) values ('value 1'),('value 2'), ('value 3');
create table #audit (id int, data_old nvarchar(max), data_new nvarchar(max), [When] datetime not null default (getdate()));
insert into #audit (id, data_old, data_new)
select id, data_old, data_new
from (
update #example
set data = 'value changed'
output inserted.id, deleted.data as data_old, inserted.data as data_new
where id = 2
)changed (id, data_old, data_new)
where data_old <> data_new
select * from #audit
will result with this in #audit :
You have described what a trigger does.
create trigger trig_member_insert on members after update
as
begin
insert into notifications ( . . . )
select . . ., i.points as new_points u.points as old_points -- what you want to insert
from inserted i join
updated u
on i.member_id = u.member_id
where u.points <> i.points
end;
Storing something called "points" as a string seems like a very poor choice. It sounds like a number.

Using OUTPUT INTO with from_table_name in an INSERT statement [duplicate]

This question already has answers here:
Is it possible to for SQL Output clause to return a column not being inserted?
(2 answers)
Closed 2 years ago.
Microsoft's OUTPUT Clause documentation says that you are allowed to use from_table_name in the OUTPUT clause's column name.
There are two examples of this:
Using OUTPUT INTO with from_table_name in an UPDATE statement
Using OUTPUT INTO with from_table_name in a DELETE statement
Is it possible to also use it in an INSERT statement?
INSERT INTO T ( [Name] )
OUTPUT S.Code, inserted.Id INTO #TMP -- The multi-part identifier "S.Code" could not be bound.
SELECT [Name] FROM S;
Failing example using table variables
-- A table to insert into.
DECLARE #Item TABLE (
[Id] [int] IDENTITY(1,1),
[Name] varchar(100)
);
-- A table variable to store inserted Ids and related Codes
DECLARE #T TABLE (
Code varchar(10),
ItemId int
);
-- Insert some new items
WITH S ([Name], Code) AS (
SELECT 'First', 'foo'
UNION ALL SELECT 'Second', 'bar'
-- Etc.
)
INSERT INTO #Item ( [Name] )
OUTPUT S.Code, inserted.Id INTO #T -- The multi-part identifier "S.Code" could not be bound.
SELECT [Name] FROM S;
No, because an INSERT doesn't have a FROM; it has a set of values that are prepared either by the VALUES keyword, or from a query (and even though that query has a FROM, you should conceive that it's already been run and turned into a block of values by the time the insert is done; there is no s.code any more)
If you want to output something from the table that drove the insert you'll need to use a merge statement that never matches any records (so it's only inserting) instead, or perhaps insert all your data into #tmp and then insert from #tmp into the real table - #tmp will thus still be the record of rows that were inserted, it's just that it was created to drive the insert rather than as a consequence of it (caveats that it wouldn't contain calculated columns)

SQL Server stored procedure to insert in multiple tables a [duplicate]

This question already has answers here:
How to get the identity of an inserted row?
(15 answers)
Closed 5 years ago.
I have 2 tables, custlogin and custinfo:
custlogin:
custid int primary key auto notnull
custusename varchar(25)
custpassword varchar(50)
custinfo:
custid foriegnkey custlogin.custid ondelete set NULL
custfirstname varchar(25)
custlastname varchar(25)
custaddress varchar(100)
I want to write a stored procedure which will insert into both tables
More precisely, insert into custlogin with custusername custpassword, which would return custid for use as foreign key for custinfo.
I have searched much but I didn't find any solution.
If you insert 1 row to custlogin, you could use ##IDENTITY or Scope_identity() to get new inserted id.
If you insert multiple rows, then use OUTPUT to get multiple new inserted ids.
You could see an example here: http://rextester.com/TWXO81648
It will be something like below. You can use SCOPE_IDENTITY() to get the last autogenerated ID withing the scope which is this stored proc in this case:
create procedure NameOfYourProcedureHere
as
begin
insert into custlogin(custusename, custpassword)
values ('','') -- put values here (from parameters?)
insert into custinfo(custid, custfirstname, custlastname, custaddress)
values (SCOPE_IDENTITY(), '', '', '') -- put other values here (from parameters?)
end

Select row just inserted without using IDENTITY column in SQL Server 2012

I have a bigint PK column which is NOT an identity column, because I create the number in a function using different numbers. Anyway, I am trying to save this bigint number in a parameter #InvID, then use this parameter later in the procedure.
ScopeIdentity() is not working for me, it saved Null to #InvID, I think because the column is not an identity column. Is there anyway to select the record that was just inserted by the procedure without adding an extra ID column to the table?
It would save me a lot of effort and work if there is a direct way to select this record and not adding an id column.
insert into Lab_Invoice(iID, iDate, iTotal, iIsPaid, iSource, iCreator, iShiftID, iBalanceAfter, iFileNo, iType)
values (dbo.Get_RI_ID('True'), GETDATE(),
(select FilePrice from LabSettings), 'False', #source, #user, #shiftID, #b, #fid, 'Open File Invoice');
set #invID = CAST(scope_identity() AS bigint);
P.S. dbo.Get_RI_ID('True') a function returns a bigint.
Why don't you use?
set #invId=dbo.Get_RI_ID('True');
insert into Lab_Invoice(iID,iDate,iTotal,iIsPaid,iSource,iCreator,iShiftID,iBalanceAfter,iFileNo,iType)
values(#invId,GETDATE(),(select FilePrice from LabSettings),'False',#source,#user,#shiftID,#b,#fid,'Open File Invoice');
You already know that big id value. Get it before your insert statement then use it later.
one way to get inserted statement value..it is not clear which value you are trying to get,so created some example with dummy data
create table #test
(
id int
)
declare #id table
(
id int
)
insert into #test
output inserted.id into #id
select 1
select #invID=id from #id