insert into select not exists sql server multiple columns primary key voilation - sql

I have a table tblApply which have primary key(email_id, Job_id) which are foreign key of tblEmail(email) and tblJob(Job_id). I want to insert new values in tblApply but avoid those which are already there in a combination of email_id, Job_id. Below is my code. How should i do it. I am doing this inside a stored procedure.
insert into tblApply(email_Id, Job_Id, Apply_Date)
select #emailId, tblJobsJob_Id, GetDate() from tblJobs
where Job_Active = 1

Well from what I understand you wish to design a stored procedure for inserting rows that will avoid inserting duplicate unique key values.
If that's the case you could do:
insert into tblApply(email_Id, Job_Id, Apply_Date)
select #emailId, tblJobsJob_Id, GetDate() from tblJobs
where Job_Active = 1 AND
NOT EXISTS(SELECT 1 FROM tblApply
WHERE email_Id = #emailId AND Job_Id = tblJobsJob_Id)

To insert the non-existing records, you can use the condition check by LEFT JOIN with NULL check.
INSERT INTO tblApply (email_Id, Job_Id, Apply_Date)
SELECT #emailId, tblJobsJob_Id, GetDate()
FROM tblJobs TJ
LEFT JOIN tblApply TA ON TA.email_id = #emailId AND TA.Job_id = TJ.tblJobsJob_Id
WHERE TY.Job_Active = 1 AND TA.Job_id IS NULL

Related

Insert into a table based on the foreign keys from other tables

I have one table containing multiple foreign keys. When I insert values into other tables, this table needs to show the inserted foreign keys. Also, ContactDate should be the current date.
When I try to execute the following, I only have inserted ContactDetails, and the rest are all NULL.
EXEC usp_addQuickContacts 'minnie.mouse#disney.com','John
Lasseter','Minnie getting Homework Support from John','Homework
Support'
I have also tried inserting them one by one instead of the inner join, but the result doesn't line up in the same row.
CREATE OR ALTER PROCEDURE usp_addQuickContacts
(
#StudentEmail VARCHAR(100),
#EmployeeName NVARCHAR(100),
#ContactDetails NVARCHAR(200),
#ContactType NVARCHAR(100)
)
AS
BEGIN
IF #contactDetails NOT IN (SELECT ContactDetails FROM StudentContacts)
INSERT INTO StudentContacts(ContactDetails)
VALUES (#contactDetails )
IF #StudentEmail NOT IN (SELECT Email From StudentInformation)
INSERT INTO StudentInformation(Email)
VALUES (#StudentEmail )
IF #contactType NOT IN (SELECT ContactType FROM ContactType)
INSERT INTO ContactType (ContactType)
VALUES (#contactType)
IF #EmployeeName NOT IN (SELECT EmployeeName FROM Employees)
INSERT INTO Employees (EmployeeName)
VALUES (#EmployeeName )
INSERT INTO StudentContacts(StudentID, EmployeeID, ContactDetails, ContactDate, ContactTypeID)
SELECT si.StudentID, e.EmployeeID, sc.ContactDetails, sc.ContactDate,ct.ContactTypeID
FROM StudentContacts sc
INNER JOIN StudentInformation si ON sc.StudentID = si.StudentID
INNER JOIN Employees e ON e.EmployeeID = sc.EmployeeID
INNER JOIN ContactType ct ON ct.ContactTypeID = sc.ContactTypeID
INNER JOIN StudentContacts scs ON scs.ContactDate = sc.ContactDate
WHERE (ct.ContactType= #ContactType) AND (si.Email = #StudentEmail) AND (e.EmployeeNAME = #EmployeeName ) AND (sc.ContactDetails = #contactDetails) AND (sc.ContactDate = GETDATE())
END
As I understand from your code that there would may be problem in below part
(sc.ContactDate = GETDATE())
Casting is not a good Option in where condition but you can try with as (Cast(sc.ContactDate as Date) = Cast(GETDATE()) as Date)

How to write a check to avoid the message "INSERT statement conflicted with the FOREIGN KEY constraint"?

I read and understood the entries in following asked question: INSERT statement conflicted with the FOREIGN KEY constraint
. I do get the point, however, I'm in this situation where I have around 1 Gb of records need to be inserted into a table, some of those records have conflicted foreign key. The query looks like this:
IF NOT EXISTS (SELECT * FROM [dbo].[tbl_R_TaskHistory] WHERE [TaskID] =
10000529)
BEGIN insert into [dbo].[tbl_History]
([TaskID],[UserID],[ActD],[RequestD],[No],[SignID],[Completed])
values (10000529,'A0000187',NULL,5738366,0,NULL,CAST(N'2011-03-16
04:53:37.210' AS DateTime)) END
The conflict ocurs on RequestID, so I was thinking there must be a way to make a check to avoid the error messages.
My point is that I want my query to check if the RequestID has not FOREIGN KEY constraint it will not insert this record and move to the next one.
If your query contains only one row, you can just expand the check like this:
IF NOT EXISTS (SELECT * FROM [dbo].[tbl_R_TaskHistory] WHERE [TaskID] = 10000529) AND EXISTS(SELECT 1 FROM [dbo].[...referencing table...] WHERE [RequestD] = 5738366)
BEGIN
insert into [dbo].[tbl_History] ([TaskID],[UserID],[ActD],[RequestD],[No],[SignID],[Completed])
values (10000529,'A0000187',NULL,5738366,0,NULL,CAST(N'2011-03-16 04:53:37.210' AS DateTime));
END
Anyway, if you are inserting many rows at the same time and for performance considerations, it will be better to store the values in buffer table. Something like this:
insert into #tbl_History ([TaskID],[UserID],[ActD],[RequestD],[No],[SignID],[Completed])
values (10000529,'A0000187',NULL,5738366,0,NULL,CAST(N'2011-03-16 04:53:37.210' AS DateTime))
,(...)
,(...)
,(...)
Then, just perform an inner join to your referencing table:
insert into [dbo].[tbl_History] ([TaskID],[UserID],[ActD],[RequestD],[No],[SignID],[Completed])
SELECT [TaskID],[UserID],[ActD],[RequestD],[No],[SignID],[Completed]
FROM #tbl_History A
INNER JOIN [dbo].[...referencing table...] B
ON A.[RequestD] = B.[RequestD];
This syntax also works
declare #a int = 5;
declare #b int = 18;
insert into sample (a, b)
select #a, #b
where not exists (select 1 from sample where b = #b)
and exists (select 1 from student where iden = #a)
This avoids creating a #temp
insert into sample (a, b)
select a, b
from ( values (5,19)
, (5,30)
, (5,31)
, (5,32)
, (7,41)
, (7,42)
) v(a,b)
where not exists (select 1 from sample where b = v.b)
and exists (select 1 from student where iden = v.a)

Constructing single select statement that returns order depends on the value of a column in SQL Server

Table1
Id bigint primary key identity(1,1)
Status nvarchar(20)
Insert dummy data
Insert into Table1 values ('Open') --1
Insert into Table1 values ('Open') --2
Insert into Table1 values ('Grabbed') --3
Insert into Table1 values ('Closed') --4
Insert into Table1 values ('Closed') --5
Insert into Table1 values ('Open') --6
How would I construct a single select statement which orders the data where records with 'Grabbed' status is first, followed by 'Closed', followed by 'Open' in SQL Server
Output:
Id Status
3 Grabbed
4 Closed
5 Closed
1 Open
2 Open
6 Open
I think you need something like this:
select *
from yourTable
order by case when Status = 'Grabbed' then 1
when Status = 'Closed' then 2
when Status = 'Open' then 3
else 4 end
, Id;
[SQL Fiddle Demo]
Another way is to using CTE like this:
;with cte as (
select 'Grabbed' [Status], 1 [order]
union all select 'Closed', 2
union all select 'Open', 3
)
select t.*
from yourTable t
left join cte
on t.[Status] = cte.[Status]
order by cte.[order], Id;
[SQL Fiddle Demo]
This could be done much better with a properly normalized design:
Do not store your Status as a textual content. Just imagine a typo (a row with Grabed)...
Further more a lookup table allows you to add side data, e.g. a sort order.
CREATE TABLE StatusLookUp(StatusID INT IDENTITY PRIMARY KEY /*you should name your constraints!*/
,StatusName VARCHAR(100) NOT NULL
,SortRank INT NOT NULL)
INSERT INTO StatusLookUp VALUES
('Open',99) --ID=1
,('Closed',50)--ID=2
,('Grabbed',10)--ID=3
CREATE TABLE Table1(Id bigint primary key identity(1,1) /*you should name your constraints!*/
,StatusID INT FOREIGN KEY REFERENCES StatusLookUp(StatusID));
Insert into Table1 values (1) --1
Insert into Table1 values (1) --2
Insert into Table1 values (3) --3
Insert into Table1 values (2) --4
Insert into Table1 values (2) --5
Insert into Table1 values (1) --6
SELECT *
FROM Table1 AS t1
INNER JOIN StatusLookUp AS s ON t1.StatusID=s.StatusID
ORDER BY s.SortRank;
I find that the simplest method uses a string:
order by charindex(status, 'Grabbed,Closed,Open')
or:
order by charindex(',' + status + ',', ',Grabbed,Closed,Open,')
If you are going to put values in the query, I think the easiest way uses values():
select t1.*
from t1 left join
(values ('Grabbed', 1), ('Closed', 2), ('Open', 3)) v(status, priority)
on t1.status = v.status
order by coalesce(v.priority, 4);
Finally. This need suggests that you should have a reference table for statuses. Rather than putting the string name in other tables, put an id. The reference table can have the priority as well as other information.
Try this:
select Id,status from tablename where status='Grabbed'
union
select Id,status from tablename where status='Closed'
union
select Id,status from tablename where status='Open'

Prevent insertion of duplicates

I have a table with columns CompanyID, EmployeeCode. EmployeeCode is unique and CompanyID can be repeated. So we can keep a list of employees in Google, Apple etc.
I want a way to ensure that the same employee cannot be added if he/she is already in the database. What would be a good way to do this ? I'd prefer not to create additional columns or tables for this.
Create a UNIQUE constraint on the column where you want to prevent duplicates:
CREATE UNIQUE INDEX [IX_YourTableName_EmployeeCode] ON [YourTableName] (EmployeeCode)
Try this..
Create table UniqueTable
(
CompanyID int,
EmployeeCode int
)
--Insert dummy data
INSERT INTO UniqueTable(EmployeeCode ,CompanyID ) Values(1,200)
--When are Going to insert duplicate Ecmployeecode '1' then it will not insert data into table
INSERT INTO UniqueTable(EmployeeCode ,CompanyID )
Select 1,200 From UniqueTable t1
Left join UniqueTable t2 on 1=t2.EmployeeCode
WHERE t2.EmployeeCode IS NULL
--We are Going to insert different Ecmployeecode '2' it will insert into table
INSERT INTO UniqueTable(EmployeeCode ,CompanyID )
Select 2,300 From UniqueTable t1
Left join UniqueTable t2 on 2=t2.EmployeeCode
WHERE t2.EmployeeCode IS NULL
Try this
Create PROCEDURE [dbo].[sp_Emp_Insert]
#EmployeeCode nvarchar(50)
As
Begin
if Not Exists (select EmployeeCode from YOUR_TABlE where EmployeeCode =#EmployeeCode )
Begin
Insert QUERY
End
else
Return 0
End
End

sql query serial number

I have written a stored procedure in SQL Server 2000. I want a serial number for output table.
So when I run this stored proc I get this error:
An explicit value for the identity column in table
'#tmpSearchResults1' can only be specified when a column list is used
and IDENTITY_INSERT is ON.
I have tried with set IDENTITY_INSERT #tmpSearchResults1 on
Create Procedure dbo.usp_mobile_All_KeyWord(#searchkey varchar(30))
AS
CREATE TABLE #tmpSearchResults
(
property_id varchar(255),
property_number varchar(255),
auction_date_reason varchar(255)
)
INSERT INTO #tmpSearchResults
SELECT
p.property_id, p.property_number, p.auction_date_reason
FROM
Pr p
INNER JOIN
Au a ON p.auction_id = a.auction_id
INNER JOIN
PrAdd pa ON p.property_id = pa.property_id
INNER JOIN state AS s ON s.state_id=pa.state
where
(
(p.archive = 'N'
AND
a.show_on_site = 'Y'
AND
(
(
((p.auction_date >= CONVERT(datetime, CONVERT(varchar, GETDATE(), 103), 103) and (p.auction_date_reason is null or p.auction_date_reason = ''))
or
(p.auction_date <= CONVERT(datetime, CONVERT(varchar, GETDATE(), 103), 103) and ( p.auction_date_reason = 'Accepting Offers' )))
and
pa.property_address_type_id = 1 )) )
and
(state_abbreviation=#searchkey or s.state_name like '%'+''+ #searchkey +''+'%' or city like '%'+''+ #searchkey +''+'%' or pa.address1 like '%'+''+ #searchkey +''+'%'
or pa.address2 like '%'+''+ #searchkey +''+'%')
)
)
CREATE TABLE #tmpSearchResults1
(
i1 int identity,
property_id varchar(255),
property_number varchar(255),
auction_date_reason varchar(255)
)
insert into #tmpSearchResults1
select
property_id ,
property_number,
auction_date_reason
from #tmpSearchResults
order by
case when charindex(#searchkey,state) >0 then 1000 else 0 end desc,
case when charindex(#searchkey,statename) >0 then 1000 else 0 end desc,
case when charindex(#searchkey,city) >0 then 1000 else 0 end desc,
case when charindex(#searchkey,address2) >0 then 1000 else 0 end desc,
case when charindex(#searchkey,address1) >0 then 1000 else 0 end desc,
case when charindex(#searchkey,short_description) >0 then 1000 else 0 end desc
select * from #tmpSearchResults1
Plz do help me
The error code is very very very clear.
The relevant portion is ...when a column list is used....
You need to specify your column list in the INSERT statement.
INSERT INTO #tmpSearchResults
(i1,
property_id,
property_number,
auction_date_reason)
SELECT
p.property_id, p.property_number, p.auction_date_reason
FROM...
First, there is a comma too much in the SELECT part of your second statement:
insert into #tmpSearchResults1
select
property_id ,
property_number,
auction_date_reason , <-- THIS ONE!!
from #tmpSearchResults
The last column of a SELECT statement must be without a comma.
So this would be correct:
insert into #tmpSearchResults1
select
property_id ,
property_number,
auction_date_reason
from #tmpSearchResults
Second, did you read this part of the error message?
An explicit value [...] can only be specified when a column list is used
The "column list" part means that you have to specify the columns in the INSERT part:
insert into #tmpSearchResults1
(property_id, property_number, auction_date_reason)
select
property_id ,
property_number,
auction_date_reason
from #tmpSearchResults
You can get away with not specifying the columns when the number of columns in the SELECT statement is the same as in the table in which they should be inserted (and if the data types match).
If one of these conditions is not met, you need to specify the columns because otherwise SQL Server doesn't know which value to insert into which column.