SQL Server IF NOT EXISTS Usage?
Have you verified that there is in fact a row where Staff_Id = @PersonID? What you've posted works fine in a test script, assuming the row exists. If you comment out the insert statement, then the error is raised.
set nocount on
create table Timesheet_Hours (Staff_Id int, BookedHours int, Posted_Flag bit)
insert into Timesheet_Hours (Staff_Id, BookedHours, Posted_Flag) values (1, 5.5, 0)
declare @PersonID int
set @PersonID = 1
IF EXISTS
(
SELECT 1
FROM Timesheet_Hours
WHERE Posted_Flag = 1
AND Staff_Id = @PersonID
)
BEGIN
RAISERROR('Timesheets have already been posted!', 16, 1)
ROLLBACK TRAN
END
ELSE
IF NOT EXISTS
(
SELECT 1
FROM Timesheet_Hours
WHERE Staff_Id = @PersonID
)
BEGIN
RAISERROR('Default list has not been loaded!', 16, 1)
ROLLBACK TRAN
END
ELSE
print 'No problems here'
drop table Timesheet_Hours
When using IF NOT EXISTS(SELECT... in Sql Server, does it matter which columns you choose?
I think it was back in the 6.5 - 7 period of SQL Server that they made the query optimizer smart enough to know that:
IF NOT EXISTS(SELECT * FROM Countries WHERE Name = 'France')
Does not actually need to return any row data. The advice to use SELECT 1
pre-dates that, yet continues on as a myth.
Arguably, it's a fault with the SQL standard - they ought to allow EXISTS
to start with the FROM
clause and not have a SELECT
portion at all.
And from Subqueries with EXISTS:
The select list of a subquery introduced by EXISTS almost always consists of an asterisk (*). There is no reason to list column names because you are just testing whether rows that meet the conditions specified in the subquery exist.
MS SQL query - if not exists a table
What you have to do is dynamically call the sysobjects table to get if the table exists and then conditionally choose what you want to insert into your temp table.
This probably the code you need:
CREATE TABLE #temp
(
DB VARCHAR(50),
Tab VARCHAR(50),
[COUNT] INT
)
DECLARE @str NVARCHAR(1000)
DECLARE @db_name NVARCHAR (150)
DECLARE @tab1 NVARCHAR (150)
DECLARE @count INT
set @tab1 = 'dbo.test'
DECLARE c_db_names CURSOR FOR
SELECT name
FROM sys.databases
WHERE name like '%KNF%'
OPEN c_db_names
FETCH c_db_names INTO @db_name
WHILE @@Fetch_Status = 0
BEGIN
SET @str = N'Select @internalVariable = (select count(1) from ' + @db_name + '.dbo.sysobjects where name = ''' + replace(@tab1, 'dbo.','') + ''') '
exec sp_executesql
@str, --dynamic query
N'@internalVariable int output', --query parameters
@internalVariable = @count output --parameter mapping
IF ( @count = 1 )
BEGIN
EXEC('
INSERT INTO #temp
SELECT ''' + @db_name + ''',''' + @tab1 + ''',COUNT(*) FROM ' + @db_name + '.' + @tab1 + '
')
END
ELSE
BEGIN
EXEC('
INSERT INTO #temp
SELECT ''' + @db_name + ''',''no table'', null
')
end
FETCH c_db_names INTO @db_name
END
CLOSE c_db_names
DEALLOCATE c_db_names
SELECT * FROM #temp
DROP TABLE #temp
SQL Server Insert if not exists
instead of below Code
BEGIN
INSERT INTO EmailsRecebidos (De, Assunto, Data)
VALUES (@_DE, @_ASSUNTO, @_DATA)
WHERE NOT EXISTS ( SELECT * FROM EmailsRecebidos
WHERE De = @_DE
AND Assunto = @_ASSUNTO
AND Data = @_DATA);
END
replace with
BEGIN
IF NOT EXISTS (SELECT * FROM EmailsRecebidos
WHERE De = @_DE
AND Assunto = @_ASSUNTO
AND Data = @_DATA)
BEGIN
INSERT INTO EmailsRecebidos (De, Assunto, Data)
VALUES (@_DE, @_ASSUNTO, @_DATA)
END
END
Updated : (thanks to @Marc Durdin for pointing)
Note that under high load, this will still sometimes fail, because a second connection can pass the IF NOT EXISTS test before the first connection executes the INSERT, i.e. a race condition. See stackoverflow.com/a/3791506/1836776 for a good answer on why even wrapping in a transaction doesn't solve this.
How to use EXISTS and NOT EXISTS in one query?
The condition:
NOT EXISTS (SELECT * FROM Table3)
...is always false if there are any rows in Table3, so your query returns no rows.
You need to add a predicate to show how Table3 rows are qualified, as shown in bold below:
SELECT Table1.Id
FROM Table1 AS Table1
WHERE EXISTS
(
SELECT 1
FROM Table2 AS Table2
WHERE
Table1.DemoID = Table2.DemoID
AND Table2.IsTrue= 1
)
AND NOT EXISTS
(
SELECT 1
FROM Table3
WHERE
Table3.Table1_ID = Table1.Id -- New
);
Demo: db<>fiddle
SQL Server : multiple WHERE NOT EXISTS clauses
Your EXISTS clause excludes all lines where any one of the conditions is TRUE, not only lines where all conditions are TRUE. Try this:
INSERT INTO Load_Charges
SELECT *
FROM Load_Charges_IMPORT
WHERE NOT EXISTS (
SELECT *
FROM Load_Charges
WHERE Load_Charges_IMPORT.[Load ID]=Load_Charges.[Load ID]
AND Load_Charges_IMPORT.[Charge Description]=Load_Charges.[Charge Description]
AND Load_Charges_IMPORT.[Charged Amount]=Load_Charges.[Charged Amount]);
Understanding NOT EXISTS in SQL
So, the original problem was to:
Retrieve the names of each employee who works on ALL the projects controlled by department 5.
The provided answer makes use of the equivalence of:
- All x such that f(x)
- No x such that not f(x)
To put that in English, the problem is equivalent to finding those employees for whom there is no project controlled by department 5 that the employee doesn't work on.
So, first find all the projects controlled by department 5, then remove from that any project that the employee works on. That's exactly what the provided answer is doing. If there is nothing left, then there is no project controlled by department 5 that the employee doesn't work on. So by the equivalance, the employee works on all the projects controlled by that department.
While this is technically correct, it can feel a little odd. Especially if it were the case that department 5 controls zero projects. If that were true, the query would return all the employees ... which might not be quite what was expected.
Related Topics
I Don't Understand Collation? (Mysql, Rdbms, Character Sets)
How to Insert Null Values into SQL Server
Remove Duplicates in a Django Query
Sqlite Format Number with 2 Decimal Places Always
Update Values in Identity Column
How to Find All Rows with a Null Value in Any Column Using Postgresql
Subtract One Day from Datetime
Why Doesn't SQL Server Support Unsigned Datatype
Is There a Coalesce-Like Function in Excel
SQL Join on Nearest Less Than Date
A How to Escape %% When Building Like Queries in Rails 3/Activerecord
Why Even Use *Db.Exec() or Prepared Statements in Golang
How to Select Bottom Most Rows
Sql: Combine Select Count(*) from Multiple Tables
How to Compare Data Between Two Table in Different Databases Using SQL Server 2008