migration script sql server for inserting an item - sql

I am trying to create an Migration Script but i need some help:, i had the very basic script to insert an item into a table but i am trying to do it in a way to check for the item first if it exists, then insert it else skip it
here is my code:
use mydatabase;
INSERT INTO dbo.mytable(col1,col2,col3)
SELECT '3','test1','test3/abc.html';

You don't need to repeat the expression just use value construct like that :
INSERT INTO dbo.mytable(col1,col2,col3)
SELECT t.col1, t.col2, t.col3
FROM (values (3, 'test1','test3/abc.html')) t (col1, col2, col3)
WHERE NOT EXISTS (
SELECT 1
FROM dbo.mytable m
WHERE m.col1 = t.col1
AND m.col2 = t.col2
AND m.col3 = t.col3
);

INSERT INTO dbo.mytable(col1,col2,col3)
SELECT '3','test1','test3/abc.html'
WHERE NOT EXISTS (
SELECT 1
FROM dbo.mytable
WHERE col1='3'
AND col2='test1'
AND col3='test3/abc.html'
)
You can change the where depending on what you consider already inserted.

Something like this (but you would need some kind of key to identify if the record exists or not) -
IF NOT EXISTS(SELECT 1 FROM dbo.mytable WHERE col1 = '3' AND col2 = 'test1' AND col3 = 'test3/abc.html')
BEGIN
insert into dbo.mytable(col1,col2,col3)
SELECT '3','test1','test3/abc.html'
END

Use a MERGE:
CREATE TABLE #mytable (col1 nvarchar(20), col2 nvarchar(20), col3 nvarchar(20))
INSERT INTO #mytable(col1,col2,col3)
SELECT '3','test1','test3/abc.html';
Merge #mytable t
USING (SELECT '3','test1','test3/abc.html') s (col1, col2, col3)
ON t.col1 = s.col1
AND t.col2 = s.col2
AND t.col3 = s.col3
when not matched by target then
INSERT (col1,col2,col3) VALUES (s.col1, s.col2, s.col3);

Related

How to write a where on column base another column?

I have table with two columns: col1 and col2.
I want to create select that return all the rows except where I have col1 != foobar AND col2 is bar_id or foo_id.
But no matter what I did it not work:
select * from table1 where col1 != 'foobar' and (col2 = 'bar_id' or col2 = 'foo_id')
select * from table1 where (col2 = 'bar_id' or col2 = 'foo_id') and col1 = 'foobar'
SELECT * FROM table1 WHERE NOT col1 = 'foobar' AND (col2 = 'bar_id' OR col2 = 'foo_id');
So how should I write the correct sql select? I want to remove ('foobar', 'foo_id'), ('foobar', 'bar_id') from the results.
sqlfiddle
the expect result:
sql
CREATE TABLE Table1
([col1] varchar(6), [col2] varchar(11))
;
INSERT INTO Table1
([col1], [col2])
VALUES
('bar', 'text'),
('foo', 'foo_id'),
('foo', 'description'),
('foobar', 'foo_id'),
('foobar', 'bar_id'),
('foobar', 'update')
;
select * from table1 where NOT (col1 = 'foobar' and (col2 = 'bar_id' or col2 = 'foo_id'))
try it
SELECT * FROM table1 WHERE NOT col1 = 'foobar' AND (col2 = 'bar_id' OR col2 = 'foo_id');
You can try using EXCEPT in SQL
select col1,col2 from table1 except select col1,col2 from table1 where col1 ='foobar' and col2 in ('bar_id','foo_id');
Not a very clean and optimized solution, but can do the job.
I want to create select that return all the rows except where I have col1 != foobar AND col2 is bar_id or foo_id.
This logic as expressed would be:
WHERE NOT (col1 <> 'foobar' AND col2 IN ('bar_id', 'foo_id') );
This can be simplified to:
WHERE col1 = 'foobar' OR col2 NOT IN ('bar_id', 'foo_id') );
This is not equivalent to the answer you accepted, so I'm wondering my interpretation of your logic is correct. However, this is specifically what your question is asking for.

Copy parent and child rows into same table?

I have a situation similar to this SO question where I want to copy parent rows and their child rows from and into the same table.
The suggested answer using OUTPUT and MERGE is clean but only considers just one record.
Is there a way to modify it to handle multiple parent rows?
EDIT
I tried to modify the SQL statement and came up with this:
DECLARE #fromId int, #toId int;
SET #fromId = 1;
SET #toId = 2;
DECLARE #mapping TABLE (old_id int, new_id int);
INSERT INTO parent_table (col1, col2, col3)
SELECT #toId, col2, col3
FROM parent_table
WHERE col1 = #fromId;
MERGE child_table tgt
USING (
SELECT t.parent_id, t.col2, t.col3
FROM child_table t
inner join parent_table p on p.id = t.parent_id
WHERE p.col1 = #toId
) src
ON 0 = 1
WHEN NOT MATCHED THEN
INSERT (parent_id, col2, col3) VALUES (src.parent_id, src.col2, src.col3)
OUTPUT src.parent_id, INSERTED.parent_id INTO #mapping (old_id, new_id);
The first INSERT of the parent rows works. However, the second insert does insert any child rows. What am I missing?
You could make use of a UNION operator. We just have to focus on maintaining the column numbers and data types :
select <required-column names, add null if value for a column not required> from parent_table
UNION
select <required-column with null if value for that column not required> from child_table where id in(select id from parent_table);
For e.g. suppose destination has five columns, parent has three columns, child has two columns.
Then, depending on where parent ids should go, we could write :
insert into destination(col1,col2, col3, col4, col5)
select col1, null, col2, col3, null from parent_table where key in(<key values>)
UNION
select col1, col2, null, null,null from child_table where key in(<key values>);
If all records are to be copied :
insert into destination(col1,col2, col3, col4, col5)
select col1, null, col2, col3, null from parent_table
UNION
select col1, col2, null, null,null from child_table where key_column in(select key_column from parent_table);

SQL Server : How to make a Insert Into with Condition

How is the syntax to make inserts with conditions? For example: verify if the value I want to insert isn't already in the table? (considering that the column could be null)
Your description is very brief but it sounds like you want the MERGE statement.
http://technet.microsoft.com/en-us/library/bb510625.aspx
Which can be used to insert/update/delete based on if data exists or not all in one statement.
Supposing values you want to insert are variables.
You can use IF NOT EXISTS:
IF NOT EXISTS (SELECT * FROM Table1 WHERE Col1 = #Val1 AND Col2 = #Val2)
INSERT INTO Table1 (Col1, COl2) VALUES (#Val1, #Val2)
or you can use SELECT..WHERE with EXISTS
INSERT INTO Table1 (Col1, COl2)
SELECT #Val1, #Val2
WHERE NOT EXISTS (SELECT * FROM Table1 WHERE Col1 = #Val1 AND Col2 = #Val2)
or probably few more methods (NOT IN, LEFT JOIN, MERGE...)
You could use a left or right join e.g.
WITH SourceTable AS
(
SELECT
*
FROM ( VALUES
('A', 1)
,('A', 2)
,('B', 1)
,('C', 10)) nTable(nCol1, nCol2)
)
SELECT
*
INTO #SourceTable
FROM SourceTable;
WITH NewRows AS
(
SELECT
*
FROM ( VALUES
('A', 2)
,('A', 3)
,('B', 1)
,('C', 11)) nTable(nCol1, nCol2)
)
INSERT #SourceTable
(nCol1
,nCol2)
SELECT
n.nCol1
,n.nCol2
FROM #SourceTable s
RIGHT JOIN NewRows n
ON s.nCol1=n.nCol1
AND s.nCol2=n.nCol2
WHERE s.nCol1 IS NULL;
Do you mean something like this?
insert into t(col)
select 'value'
where not exists (select 1 from t where col = 'value');
However, I would recommend that you use a unique index, filtered index, or foreign key constraint to maintain data integrity.
Try this:
insert into target_table (col1, col2, ...)
select col1, col2, ...
from source_table
where col_x not in (
select col_y from target_tabke where col_y is not null)
or (col_x is null and not exists (
select * from target_table where col_y is null))

SQL get multiple values of columns in one row

I am using MS Sql server 2008 R2.
I have a query that gives me output like this
Col1....Col2
CV1.....AV1
CV1.....AV2
CV2.....AV3
CV2.....AV4
The query is
select Tab1.Col1, Tab2.Col2
from Table1 Tab1
JOIN Table2 Tab2 on Tab1.PKID = Tab2.FKID
What I want is one row for each distinct values in Col1 and in Col2 all the values related to col1 with comma or pipeline delimiter
Col1....Col2
CV1.....AV1,AV2
CV2.....AV3,AV4
Can anyone help me on this?
Basically I need something like group_concat that is available in My sql
CREATE TABLE a(
Col1 varchar(50),
Col2 varchar(20));
INSERT INTO a (Col1,Col2) values ('CV1','AV1');
INSERT INTO a (Col1,Col2) values ('CV1','AV2');
INSERT INTO a (Col1,Col2) values ('CV2','AV3');
INSERT INTO a (Col1,Col2) values ('CV2','AV4');
with t as (SELECT Col1,(CAST(Col2 AS nvarchar (12))) as col2 from a )
Select distinct T2.Col1,
substring((Select ',' + T1.col2 AS [text()]
From t T1
Where T1.Col1 = T2.Col1
ORDER BY T1.Col1
For XML PATH ('')),2, 100) [col2]
From t T2
Try this query. I am doing it in sql server. check at sqlfidddle
http://sqlfiddle.com/#!3/7ab28/1

How to get count on ths query

I'm doing an
INSERT INTO table1...
SELECT...
FROM table2
However, I need to retrieve the identity from a table3 and do an insert into it just before inserting into table1. These two inserts need to occur together, with table3 insert going first. I've tried something like this:
INSERT INTO table1 (col1, col2, col3)
SELECT (
col1=(insert into table3(col1, col2)values(1,1) select SCOPE_IDENTITY(),
col2, col3)
FROM table2
But that doesn't work. table1.col1 does need the identity value from the new insert into table3. Amount of data to insert probably no more than a few 100 rows. Any suggestions?
It looks like you might be able to use the Output Clause.
BEGIN TRANSACTION
DECLARE #MyResults table(col1 int, col2 int, col3 int);
INSERT INTO table3 (col1, col2)
OUTPUT SCOPE_IDENTITY(), table2.col2, table2.col3 INTO #MyResults
SELECT 1, 1 FROM table2
INSERT INTO table1 (col1, col2, col3)
SELECT col1, col2, col3 FROM #MyResults
COMMIT