Compare tables base on Id and generate Insert statement - sql

I have two DB(every thing is same schema, etc...) staging & Prod.
Both has table called "Prod.Product" & "Staging.Product"
I would like to compare these two tables base on id for example Id=1 and generate insert statement
select * from Prod.Product
except
select * from Staging.Product

Why do you need to generate insert statement? Just execute it. As far as I understand, you want to insert in Prod.Product the rows from Staging.Product with ID values that does not exists. You can do it like this:
insert into Prod.Product
select * from Staging.Product s
where not exists(select 1 from Prod.Product p where p.Id = s.Id)

Related

Insert into newly created column

I have a Students table with 2 col as Rollno and Marks with 12 records
I added another column in students table as Name. How do I fill Names with 12 records from another table in SQL Server?
I tried this:
SELECT * FROM [SampleDB].[dbo].[Student_SQL]
insert into Student_SQL(name)
select name
FROM [School].[dbo].[StudentMaster]
update [Student_SQL]
set name = 'David'
where RollNo = 4`
I think you want the upate/join syntax. Assuming that the two tables relate through column rollno:
update ss
set ss.name = sm.name
from student_sql ss
inner join student_master sm on sm.rollno = ss.rollno
The upside of this approach is that it filters the rows and only update those that match in the master table.
in order to do this, you need to have column in common for both tables
update [Student_SQL] s
set name = (select name from other_table o where o.roll_no = s.roll_no)

SQL Server 2005 Bulk insert on split string where not exists

I have a problem with an insert statement where I cannot get the "where not exists" clause to work. I would prefer a solution where I do not have to dump my list into a declared a table. Here are two of the solutions I have tried, could someone please tell where my syntax is wrong? My split string list has three values, the first two values would be new, but the third value already exists in the database and so should not be inserted.
With this sample I get no data returned at all:
insert into dbo.Cook(Id, CookId, DateEntered, Active)
select
#Id, value as CookId, getDate(), 1
from
dbo.Split('123456,234567,345678', ',')
left join
dbo.Cook ck on ck.Id = #Id
where
not exists (select CookId from dbo.Cook where Id = #Id)
Then I tried a version with a table which winds up returning all the values in my #ids table including the cook number that would be a duplicate:
declare #ids table (id int)
insert into #ids
select value as id
from dbo.Split('123456,234567,345678', ',')
insert into dbo.Cook(Id, CookId, DateEntered, Active)
select
#Id, id as CookId, getDate(), 1
from
#ids
left outer join
dbo.Cook ck on ck.CookId = id
where
not exists (select CookId from dbo.Cook where ck.CookId != id)
I have the solution to my problem, thanks goes out to a fellow programmer. My problem was I should have being doing the join on the select statement and adding a comparison column to get the information I was looking for. The solution was this:
insert into dbo.Cook(Id, CookId, DateEntered, Active)
select
#Id, value as CookId, getDate(), 1
from
dbo.Split('123456,234567,345678', ',') c
left join
(select cook from dbo.Cook where Id = #Id) cook on cook.Id = c.value
where
cook.Id is null
Aside from your neglecting to put your from clause on a new line cringe, I believe it is your syntax.
I don't understand what you are trying to do here. dbo.Split is not a built in function in SQL Server as far as I know.

Pre-Populate foreign keys in SQL with a new row

I am trying to write a SQL script which will go through a table with a newly created FK and pre-populate the key with a new row in the foreign table. I'm not 100% on how to do this or if its even possible in a single statement but here's my attempt:
UPDATE [dbo].[Blogs]
set AuthorSecurableId = inserted.Id
FROM [dbo].[Blogs] updating
INNER JOIN
(INSERT INTO [dbo].[Securables] (Name)
OUTPUT Inserted.id, ROW_NUMBER() OVER (ORDER BY Inserted.Id) as rownum
SELECT 'Admin : ' + Name
FROM Blogs
WHERE AuthorSecurableId is null) inserted ON ROW_NUMBER() OVER (ORDER BY updating.Id) = inserted.rownum
WHERE updating.AuthorSecurableId is null
When I do this I get the following error
Msg 10727, Level 15, State 1, Line 5
A nested INSERT, UPDATE, DELETE, or MERGE statement is not allowed on either side of a JOIN or APPLY operator.
Below is a simple view of the schema I have
I would like to create a securable for each blog which doesn't have one and populate that blogs AuthorSecurableId with the ID of the newly created securable
I think I could do this with a cursor but I was wondering if there is a better single statement approach
You can use merge against Securables with output to a table variable or temp table and a separate update against Blogs.
declare #T table
(
SecID int,
BlogID int
);
merge Securables T
using (
select 'Admin : '+B.Name as Name, B.Id
from Blogs as B
where B.AuthorSecurabledId is null
) as S
on 0 = 1
when not matched by target then
insert (Name) values (S.Name)
output inserted.Id, S.Id
into #T;
update Blogs
set AuthorSecurabledId = T.SecID
from #T as T
where Blogs.Id = t.BlogID;
SQL Fiddle

WHERE Query Scenario

I have a table in DB with various columns, one of them being Name. Suppose the Names in DB are A,B,C,D,E,F.
I wrote a query:
Select * from Table where Name IN (#ENTERED_NAMES#)
(Suppose #ENTERED_NAMES# are the various names entered by USER on GUI)
Now suppose that the user enters in the GUI the following names: A,B,C,Y,Z
Since A,B,C are valid names but Y,Z is not present in DB,
so I want the results of A,B,C as it is, but for Y,Z(invalid values) I want results of name "D" for all invalid values.
So the query should come as
Select * from Table where Name IN (A,B,C,D)
try this
first concat the string as 'A','B','C'
Select * from Table where Name IN ('A','B','C');
Something like this maybe?
-- create a table containing all valid names
create table valid_names (name varchar(20));
insert into valid_names values ('A');
insert into valid_names values ('B');
insert into valid_names values ('C');
commit;
with usernames (name) as (
values ('A'),('B'),('C'),('X'),('Y') -- this is the user input
)
select case
when vn.name is null then 'D'
else un.name
end as name,
case
when vn.name is null then 'invalid'
else 'valid'
end as name_info -- name info is just for the demo!
from usernames un
left join valid_names vn on vn.name = un.name;
returns the following:
NAME | NAME_INFO
-----+----------
A | valid
B | valid
C | valid
D | invalid
D | invalid
I'm not sure this is what you should really want, but it seems to be what you asked for:
If you have a temporary table where you insert your GUI input values, then
SELECT coalesce(t.name,'D')
FROM gui_input g
LEFT JOIN db_table t on g.name = t.name
You would be a bit better off with this:
SELECT g.name, coalesce(t.name,'*invalid*')
FROM gui_input g
LEFT JOIN db_table t on g.name = t.name
or
SELECT g.name, case when t.name is null then '*OK*' else '*invalid*' end
FROM gui_input g
LEFT JOIN db_table t on g.name = t.name
But still, I'm not sure we have quite the right question for what will best suit whatever you are trying to do.
Best thing you can do is to write a "CASE" for all the input values other than the values present in database.

sql server insert data from table1 to table2 where table1=table3 data

I am trying to insert into Table A, unique data from Table B that matches data in TAble C but I am keep getting the violation of primary key error and not sure what I am doing wrong
Table A - bookfeed
Table B - bookF
Table C - bookStats
INSERT INTO bookFeed
(entryId,feed,entryContent,pubDate,authorName,authorId,age,
sex,locale,pic,fanPage, faceTitle,feedtype,searchterm,clientId,dateadded)
SELECT DISTINCT b.entryId,b.feed,b.entryContent,b.pubDate,b.authorName,
b.authorId,b.age,b.sex,b.locale,b.pic,b.fanPage,b.faceTitle,b.feedtype,
b.searchterm, b.clientId,b.dateadded
FROM bookF as b
INNER JOIN bookStats as a on a.feed = b.feed
WHERE NOT EXISTS (SELECT *
FROM bookFeed as c
WHERE c.entryId = b.entryId)
Table A bookFeed has a primary key on entryId
It looks like in table bookF, there are duplicate records per entryId
If you only want one entryId (limited by PK on bookFeed), you can use this. Adjust the order by in the ROW_NUMBER to suit
insert into bookFeed (
entryId,feed,entryContent,pubDate,authorName,authorId,age,
sex,locale,pic,fanPage,faceTitle,feedtype,searchterm,clientId,dateadded)
select
entryId,feed,entryContent,pubDate,authorName,authorId,age,
sex,locale,pic,fanPage,faceTitle,feedtype,searchterm, clientId,dateadded
from
(
select rn=Row_number() over (partition by b.entryId order by b.entryId),
b.entryId,b.feed,b.entryContent,b.pubDate,b.authorName,b.authorId,b.age,
b.sex,b.locale,b.pic,b.fanPage,b.faceTitle,b.feedtype,b.searchterm, b.clientId,b.dateadded
from bookF as b
inner join bookStats as a on a.feed = b.feed
left join bookFeed as c on c.entryId=b.entryId
where c.entryId is null
) X
where rn=1
UPDATE : Try this for you query and see if it works,look at the data and see if there are duplicates meaning all the entries should have an entry id different than what is currently there -
SELECT b.entryId,b.feed,b.entryContent,b.pubDate,b.authorName,
b.authorId,b.age,b.sex,b.locale,b.pic,b.fanPage,b.faceTitle,b.feedtype,
b.searchterm, b.clientId,b.dateadded
FROM bookF as b
INNER JOIN bookStats as a on a.feed = b.feed
WHERE b.entryId IN (SELECT distinct entryid
FROM bookFeed)
I think you are trying to insert an entry id which is an primary key(check if the value trying to insert is not an duplicate,null or violates any other of primary key constraint)...so either dont try to insert it if it gets populated automatically or in case you are looking to insert it then turn on identity insert on..and try again...
But ideally your id should be calculated (auto increment or something) and never be inserted directly.