I want to create "UPDATE if exists else INSERT" statements for existing values in a table with the following pattern:
if exists (select 1 from TABLE_NAME where Ident_Column=Identifier )
update TABLE_NAME set
Column1=Value1,
Column2=Value2,
Column3=Value3,
...
where Ident_Column=Identifier
else
insert into TABLE_NAME ( Column1, Column2, Column3, ...)
select Value1, Value2, Value3, ...
go
I try to use the MSSQL Mangement Studio (2014) script generator, but I do not get the output as desired.
EDIT: The desired output IS the SQL statement, #Rusland K. & Nick.McDermaid . I want to use the script generator to generate this SQL code for each (or selected) rows of the table TABLE.
Identifier is not a variable, its a value.
If the value Identifier in Column Ident_Column exists, set the row accordingly (Value 1-n). If that Identifier is not found in any row, create a now row accordingly.
#bmsqldev: This is the entire code (just replaced the real column/table names and the concrete values)
Actually I'm don't understand what caused the missunderstanding here. If you can tell, I'd be happy to learn.
EDIT2: I endet up writing a small script which converts the script output of MSSQL Mangement Studio according to this pattern, which took me about 2 hours.
MERGE TABLE_NAME AS TARGET
USING(
SELECT
*
FROM
DBO.TABLE_NAME
WHERE
IDENT_COLUMN=IDENTIFIER
) AS SOURCE
ON(
TARGET.COLUMN1 = SOURCE.COLUMN1
AND TARGET.COLUMN2 = SOURCE.COLUMN2
AND TARGET.COLUMN3 = SOURCE.COLUMN3
)
WHEN MATCHED THEN UPDATE
SET
TARGET.COLUMN1=SOURCE.VALUE1,
TARGET.COLUMN2=SOURCE.VALUE2,
TARGET.COLUMN3=SOURCE.VALUE3,
WHEN NOT MATCHED THEN INSERT
(
COLUMN1, COLUMN1, COLUMN1, ...)
VALUES(
(VALUE1, VALUE2, VALUE3, ...
),
SOURCE.VALUE1,
SOURCE.VALUE2,
SOURCE.VALUE3,...
);;
Related
I often get a list of names I need to update in a table from an Excel list, and I end up creating a SSIS program to reads the file into a staging table and doing it that way. But is there I way I could just copy and past the names into a table from Management Studio directly? Something like this:
create table #temp (personID int, userName varchar(15))
Insert
Into #temp (userName)
values (
'kmcenti1',
'ladams5',
'madams3',
'haguir1',
)
Obviously this doesn't work but I've tried different variations and nothing seems to work.
Here's an option with less string manipulation. Just paste your values between the single quotes
Declare #List varchar(max) = '
kmcenti1
ladams5
madams3
haguir1
'
Insert into #Temp (userName)
Select username=value
From string_split(replace(#List,char(10),''),char(13))
Where Value <>''
For Multiple Columns
Source:
-- This is a copy/paste from Excel --
-- This includes Headers which is optional --
-- There is a TAB between cells --
Declare #List nvarchar(max) = '
Name Age email
kmcenti1 25 kmcenti1#gmail.com
ladams5 32 ladams5#gmail.com
madams3 18 madams3#gmail.com
haguir1 36 haguir1#gmail.com
'
Select Pos1 = JSON_VALUE(JS,'$[0]')
,Pos2 = JSON_VALUE(JS,'$[1]') -- could try_convert(int)
,Pos3 = JSON_VALUE(JS,'$[2]')
From string_split(replace(replace(#List,char(10),''),char(9),'||'),char(13)) A
Cross Apply (values ('["'+replace(string_escape(Value,'json'),'||','","')+'"]') ) B(JS)
Where Value <>''
and nullif(JSON_VALUE(JS,'$[0]'),'')<>'Name'
Results
Is this along the lines you're looking for?
create table #temp (personID int identity(1,1), userName varchar(15))
insert into #temp (userName)
select n from (values
('kmcenti1'),
('ladams5'),
('madams3'),
('haguir1'))x(n);
This assumes you want the ID generated for you since it's not in your data.
That SQL statement you have won't work (That's one row). But I have a work around. Build what you need with a formula in Excel.
Assuming user IDs are in column A:
In Cell B2, insert this formula:
="('"&A1&"'),"
And then drag the formula down you list.
Go to SSMS and type in:
insert into [your table](userName) values
And then paste in column B from Excel and delete the last comma.
I know how to generate scripts to script insert lines allowing me to backup some data. I was wondering though if it was possible to write a query (using WHERE clause as an example) to target a very small subset of data in a very large table?
In the end I want to generate a script that has a bunch of insert lines and will allow for inserting primary key values (where it normally would not let you).
SSMS will not let you to have the INSERT queries for specific rows in a table. You can do this by using GenerateInsert stored procedure. For example :
EXECUTE dbo.GenerateInsert #ObjectName = N'YourTableName'
,#SearchCondition='[ColumnName]=ColumnValue';
will give you similar result for the filtered rows specified in the #SearchCondition
Let's say your table name is Table1 which has columns Salary & Name and you want the insert queries for those who have salary greater than 1000 whose name starts with Mr., then you can use this :
EXECUTE dbo.GenerateInsert #ObjectName = N'Table1'
,#SearchCondition='[Salary]>1000 AND [Name] LIKE ''Mr.%'''
,#PopulateIdentityColumn=1;
If I read your requirement correctly, what you actually want to do is simply make a copy of some data in your table. I typically do this by using a SELECT INTO. This will also generate the target table for you.
CREATE TABLE myTable (Column1 int, column2 NVARCHAR(50))
;
INSERT INTO myTable VALUES (1, 'abc'), (2, 'bcd'), (3, 'cde'), (4, 'def')
;
SELECT * FROM myTable
;
SELECT
*
INTO myTable2
FROM myTable WHERE Column1 > 2
;
SELECT * FROM myTable;
SELECT * FROM myTable2;
DROP TABLE myTable;
DROP TABLE myTable2;
myTable will contain the following:
Column1 column2
1 abc
2 bcd
3 cde
4 def
myTable2 will only have the last 2 rows:
Column1 column2
3 cde
4 def
Edit: Just saw the bit about the Primary Key values. Does this mean you want to insert the data into an existing table, rather than just creating a backup set? If so, you can issue SET IDENTITY_INSERT myTable2 ON to allow for this.
However, be aware that might cause issues in case the id values you are trying to insert already exist.
I want to compare #tempTable with tableA, if matched then update FieldValue of #tempTable equal to id of tableA; if not matched then insert values ,and get the id of tableA to update FieldValue of #tempTable.
The following is my SQL query:
create table [dbo].[TableA]([Id] int Indentity(1,1),[Data] [sql_variant] NULL)
declare #tempTable table (FieldValue nvarchar(1000),FieldType nvarchar(1000))
insert #tempTable values ('some content','A Type')
merge
tableA
using (
select
FieldValue
from
#tempTable
) x
on tableA.[Data] = x.FieldValue
when not matched then
insert values (x.FieldValue)
when matched then
update set x.FieldValue = tableA.[Id] ;
The following is the error message:
Unable to tie the Multi-Part ID "x.FieldValue".
The error looks like it's different data type between x.FieldValue and tableA.id, so I adjust them to the same data type, but it's still not work, and I don't know how to fix it.
What are you trying to achieve? Your target table is tableA, your source table is the x-aliased sub-query.
Next time please try to create a mcve. I had to modify your code slightly, but you will get the ghist:
declare #TableA TABLE([Id] int,[Data] [sql_variant] NULL)
declare #tempTable table (FieldValue nvarchar(1000),FieldType nvarchar(1000))
insert #tempTable values ('some content','A Type');
merge
#tableA a
using (
select
FieldValue
from
#tempTable
) x
on a.[Data] = x.FieldValue
when matched then
update set a.id = x.FieldValue; --fields swapped, probably not really your intention...
The point is: Your code tries to update a field of your source table. The general idea of MERGE is
We target one table where we want to insert/update/delete some records.
We use a second set with the data we want to compare and use for these operations
We find rows within the source which are missing in the target -> INSERT
We find rows within the source which are existing in the target -> UPDATE
We find rows whithin the target which are missing in the source -> DELETE
Saying this, I doubt, that the code above would need MERGE at all...
The following can achieve the results I want.
merge
tableA
using (
select
FieldValue
from
#tempTable
) x
on tableA.[Data] = x.FieldValue
when not matched then
insert values (x.FieldValue);
update #tempTable
set t.FieldValue = i.[Id]
from #tempTable t
join TableA i ON i.[Data] = t.FieldValue
select * from #tempTable
insert into ASSET_MAIN_CATEGORIES values(select max(sno) from ASSET_MAIN_CATEGORIES,
'PROD','AC HMU','AC_HMU','PRODUCT','99CS002','','NR','LKO',1);
I wanted to insert max of SNO as column value. But It is showing "Missing Expression Error"
How can I achieve this.
Any Help would be appreciated.
There are at least ways of doing it:
INSERT INTO ... VALUES with embedded select in parentheses so that database will evaluate it:
insert into ASSET_MAIN_CATEGORIES values(
(select max(sno) from ASSET_MAIN_CATEGORIES),
'PROD','AC HMU','AC_HMU','PRODUCT','99CS002','','NR','LKO',1
);
INSERT INTO ... SELECT since all other data is static:
insert into ASSET_MAIN_CATEGORIES
select
max(sno),
'PROD','AC HMU','AC_HMU','PRODUCT','99CS002','','NR','LKO',1
from ASSET_MAIN_CATEGORIES
;
Note that if you do not specify which columns you are populating in ASSET_MAIN_CATEGORIES database assumes that you're feeding values for all of them in the order that they were created in this table.
You need to surround select max with brackets, because it's a SQL statement:
insert into ASSET_MAIN_CATEGORIES values((select max(sno) from ASSET_MAIN_CATEGORIES), 'PROD','AC HMU','AC_HMU','PRODUCT','99CS002','','NR','LKO',1);
If you have an error, prefer to add column names in insert statement
this will work :-
i have checked with my tables its working ,sample code to understand:
insert into b(col1,col2) select 7,(select max(col2) from b)
from dual;
what code you require:-
insert into ASSET_MAIN_CATEGORIES(col1,col2,....,col10)
select (select max(col2) from ASSET_MAIN_CATEGORIES), 'PROD','AC
HMU','AC_HMU','PRODUCT','99CS002','','NR','LKO',1)
from dual;
I'm inserting into a table in MS SQL Server 2008 (it's rather a copy of values from the same table) and want to get the output values for the insert. I want to get the id value of the select statement (t.id in the example below), the INSERTED.id works just fine
create table tmp.tbl_inserted (fromId int, toId int)
INSERT INTO mytable (name)
OUTPUT t.id, INSERTED.id INTO tmp.tbl_inserted
SELECT t.name FROM mytable t
Thanks in advance
You can't do it directly from an INSERT:
from_table_name
Is a column prefix that specifies a table included in the FROM clause of a DELETE, UPDATE, or MERGE statement that is used to specify the rows to update or delete.
Note that INSERT isn't mentioned.
What you have to do instead is cheat and use a MERGE:
MERGE INTO mytable m
USING (name,id FROM mytable) t ON 1=0
WHEN NOT MATCHED THEN INSERT (name) VALUES (t.name)
OUTPUT t.id, INSERTED.id INTO tmp.SizeCurveGroup_inserted
;