Msg 156, Level 15, State 1, Line 16 Incorrect syntax near the keyword 'IF' - sql

-- --------------------------------------------------------
-- Host: 192.168.62.245
-- Server version: Microsoft SQL Server 2014 - 12.0.2000.8
-- Server OS: Windows NT 6.1 <X64> (Build 7601: ) (WOW64) (Hypervisor)
-- HeidiSQL Version: 9.5.0.5196
-- --------------------------------------------------------
/*!40101 SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES */;
/*!40014 SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-- Dumping database structure for mjDB
CREATE DATABASE IF NOT EXISTS "mjDB";
USE "mjDB";
-- Dumping structure for table mjDB.PushNotificationLog
CREATE TABLE IF NOT EXISTS "PushNotificationLog" (
"pushNotificationLogId" INT(10,0) NOT NULL,
"itemType" VARCHAR(20) NULL DEFAULT NULL,
"itemId" INT(10,0) NULL DEFAULT NULL,
"servicemanId" INT(10,0) NULL DEFAULT NULL,
"title" VARCHAR(100) NULL DEFAULT NULL,
"body" VARCHAR(4000) NULL DEFAULT NULL,
"tranId" INT(10,0) NULL DEFAULT NULL,
"createdBy" INT(10,0) NULL DEFAULT NULL,
"createdDate" DATETIME(3) NULL DEFAULT NULL,
PRIMARY KEY ("pushNotificationLogId")
);
I exported this one from HeidiSQL updated to 19/12/2017, when I try to run this on SQL Server 2014 I get this error:
Msg 156, Level 15, State 1, Line 16
Incorrect syntax near the keyword 'IF'.
Msg 102, Level 15, State 1, Line 16
Incorrect syntax near 'mjDB'.
Msg 911, Level 16, State 1, Line 17
Database 'mjDB' does not exist. Make sure that the name is entered correctly.

Your create table syntax is wrong if you are using SQL Server. Change the code like this if you wish to check the table existence before creating
IF object_id('PushNotificationLog') IS NULL
BEGIN
CREATE TABLE [PushNotificationLog]
(
pushNotificationLogId INT NOT NULL,
itemType VARCHAR(20) NULL DEFAULT NULL,
itemId INT NULL DEFAULT NULL,
servicemanId INT NULL DEFAULT NULL,
title VARCHAR(100) NULL DEFAULT NULL,
body VARCHAR(4000) NULL DEFAULT NULL,
tranId INT NULL DEFAULT NULL,
createdBy INT NULL DEFAULT NULL,
createdDate DATETIME NULL DEFAULT NULL,
PRIMARY KEY (pushNotificationLogId)
);
END
You can also do the check by checking the existence in the view sys.tables
IF NOT EXISTS(SELECT 1 FROM sys.tables WHERE name = 'PushNotificationLog')
BEGIN
END
Similarly Check in the master.sys.databases table for the existence of Database
IF NOT EXISTS(SELECT 1 FROM master.sys.databases WHERE name = 'mjDB')
BEGIN
END

Use single quotes (') instead of double quotes (")
Remove the quotes from the identifiers (DatabaseName, TableName)
Replace the quotes in the column names with square brackets ([])
IF NOT EXISTS
(
SELECT 1
FROM [master].sys.databases
WHERE [name] = 'mjDB'
)
BEGIN CREATE DATABASE mjDB; END
GO
USE mjDB;
GO
-- Dumping structure for table mjDB.PushNotificationLog
IF (OBJECT_ID('dbo.PushNotificationLog', 'U') IS NULL)
BEGIN
CREATE TABLE dbo.PushNotificationLog
(
[PushNotificationLogID] INT NOT NULL
, [ItemType] VARCHAR(20)
, [ItemID] INT
, [ServicemanID] INT
, [Title] VARCHAR(100)
, [Body] VARCHAR(4000)
, [TranId] INT
, [CreatedBy] INT
, [CreatedDate] DATETIME
, CONSTRAINT PK__PushNotificationLog PRIMARY KEY ([pushNotificationLogId])
);
END
GO

Related

Check column data type and change it in SQL Server

All I want to do is check if the hire_state column's data type is bit, and if so, change it to SmallInt.
Here is my code
IF OBJECT_ID(N'dbo.employees') IS NULL
BEGIN
CREATE TABLE dbo.employees
(
employees_id INT IDENTITY(1, 1) PRIMARY KEY,
employees_number INT NOT NULL,
first_name NVARCHAR(120) NOT NULL,
last_name NVARCHAR(120) NOT NULL,
birthday DATE NOT NULL,
gender TINYINT NOT NULL,
hire_date DATE NOT NULL,
phone1 NCHAR(25) NOT NULL,
phone2 NVARCHAR(25),
home_address NVARCHAR(255) NOT NULL,
granty NVARCHAR(250),
hire_state BIT NOT NULL DEFAULT 1,
leave_Date DATE,
job SMALLINT NOT NULL
);
END
ELSE
BEGIN
IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.TABLE_NAME = N'employees'
AND C.COLUMN_NAME = 'employee_image')
ALTER TABLE dbo.employees
ADD employee_image NVARCHAR(255)
ALTER TABLE dbo.employees
ALTER COLUMN hire_state TINYINT NOT NULL
END;
How can I check whether hire_state is bit or not and then change it to TinyInt?
When I execute my code shown above, I get this error
Msg 5074, Level 16, State 1, Line 49
The object 'DF__employees__hire___267ABA7A' is dependent on column 'hire_state'.
Msg 4922, Level 16, State 9, Line 49
ALTER TABLE ALTER COLUMN hire_state failed because one or more objects access this column.
I did not use hire_state in any other table
Ok I Change my code base on comment and it work
IF EXISTS (SELECT * FROM sys.columns WHERE name =
N'hire_state' AND
object_id= OBJECT_ID('dbo.employees') AND
system_type_id = 104)
BEGIN
ALTER TABLE dbo.employees DROP CONSTRAINT DF__employees__hire___267ABA7A
ALTER TABLE dbo.employees ALTER COLUMN hire_state TINYINT NOT NULL
END;

SQL Server (SSMS) Losing or Not Recognizing Transaction

I've run into an issue a couple times now where I'll encase a query in BEGIN TRAN / ROLLBACK TRAN (so I can verify it works before committing any changes), and will get the error below. The BEGIN TRAN statement does not generate an error.
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
The commands I was using the most recent time are below. I didn't save the errors at the time, but I believe that the UPDATE commands also errored because it didn't recognize ClientId as a valid column.
Each time it has done this, some statements have been rolled back, and others remained. In this case, I have neither a ClientId nor a ClientCode column.
I also can't perfectly recreate the initial run since running these outside of a transaction has caused me to lose all of my ClientCode fields, and the ClientId fields are not in the tables. Thankfully, none of the dev data was important, but because of its volume, it'll take me a little bit to repopulate.
Initially, I thought I'd just selected some of the query before running it, ommiting the BEGIN TRAN, so I reran it, careful to select everything and got the same error, as well as a host of others caused by the missing ClientCode field.
I'd like to know why this is happening so I can prevent it in the future.
EDIT: I did some additional testing on a later date and I have been unable to recreate this behavior. The transactions are being rolled back correctly, and the UPDATE command is not erroring for having an invalid column
BEGIN TRAN
ALTER TABLE tblInvoices ADD ClientId INT NULL
GO
UPDATE tblInvoices
SET ClientId = c.Id
FROM tblInvoices i
INNER JOIN Core.dbo.tblClients c
ON i.ClientCode = c.ClientCode
GO
ALTER TABLE tblInvoices ALTER COLUMN ClientId INT NOT NULL
GO
ALTER TABLE tblInvoices DROP COLUMN ClientCode
GO
ALTER TABLE tblClientSettings ADD ClientId INT NULL
GO
UPDATE tblClientSettings
SET ClientId = c.Id
FROM tblClientSettings cs
INNER JOIN Core.dbo.tblClients c
ON cs.ClientCode = c.ClientCode
GO
ALTER TABLE tblClientSettings ALTER COLUMN ClientId INT NOT NULL
GO
ALTER TABLE tblClientSettings DROP COLUMN ClientCode
GO
ROLLBACK TRAN
EDIT 2: It happened again on a small set of commands. The commands and the output messages are below.
Input:
BEGIN TRAN
CREATE TABLE tblEmailTemplates(
Id INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
Subject NVARCHAR(2000) NULL,
Body NVARCHAR(MAX) NULL,
Sender NVARCHAR(200) NULL,
Recipients NVARCHAR(2000) NULL,
CC NVARCHAR(2000) NULL,
BCC NVARCHAR(2000) NULL,
Html BIT NULL
)
CREATE TABLE tblContactSeries (
Id INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
AppId INT NOT NULL REFERENCES Foo_Apps.dbo.tblApps(Id),
Description NVARCHAR(200) NOT NULL
)
CREATE TABLE [dbo].tblEmails(
[Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
SeriesId INT NOT NULL REFERENCES tblContactSeries(Id),
TemplateId INT NULL REFERENCES tblEmailTemplates(Id),
TemplateParameters NVARCHAR(MAX) NULL,
[Sender] [nvarchar](200) NULL,
[Recipients] [nvarchar](2000) NULL,
[CC] [nvarchar](2000) NULL,
[BCC] [nvarchar](2000) NULL,
[Subject] [nvarchar](2000) NULL,
[Body] [nvarchar](max) NULL,
[Html] [bit] NOT NULL,
[ScheduledDate] [datetime] NOT NULL,
[OverdueDate] [datetime] NULL,
[Active] [bit] NOT NULL,
[Sent] [bit] NOT NULL,
[SendTime] [datetime] NULL,
[SendSuccess] [bit] NULL
)
CREATE TABLE [dbo].[tblAttachments](
[Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
EmailId [int] NOT NULL REFERENCES tblEmails(Id),
[FilePath] [nvarchar](2000) NULL,
[FileName] [nvarchar](200) NULL
)
GO
CREATE VIEW vwPendingAttachments AS
SELECT a.*
FROM tblAttachments a
INNER JOIN tblEmails e
ON a.EmailId = e.Id
WHERE e.Active = 1 AND e.Sent != 1
GO
ROLLBACK TRAN
Messages:
Msg 1763, Level 16, State 0, Line 23
Cross-database foreign key references are not supported. Foreign key 'Foo_Apps.dbo.tblApps'.
Msg 1750, Level 16, State 1, Line 23
Could not create constraint or index. See previous errors.
Msg 208, Level 16, State 1, Procedure vwPendingAttachments, Line 4 [Batch Start Line 59]
Invalid object name 'tblAttachments'.
Msg 3903, Level 16, State 1, Line 70
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.

What is wrong with this access query?

Running the below query returns 0 records, but I would expect it to return 3.
SELECT
ID,
DW2_TV_DimStation_Id,
DW2_OTT_DimStation_Id,
Name,
CoreTVCode,
CoreOTTCode,
StrataTVCode,
HouseHolds,
MaleSkew,
FemaleSkew,
AverageAge,
AverageIncome,
BroadReach,
Description,
Owner,
Notes,
timestamp,
CreatedOn,
ModifiedOn,
Retired,
1 AS Accepted
FROM
Planning_DimStation AS src
WHERE
src.[timestamp] = (
SELECT
MAX([timestamp])
FROM
Planning_DimStation AS src2
WHERE
src2.[ID] = src.[ID]
)
AND NOT EXISTS (
SELECT
1
FROM
DimStation AS tgt
WHERE
tgt.[ID] = src.[ID]
);
The part that breaks it is the NOT EXISTS statement. If I delete the NOT EXISTS it works fine.
Table 1: Planning_DimStation
Is an SQL table linked with 3 records in it. Source below.
Table 2: DimStation
Is an Access table (pic of source UI below) that is empty
Could this be a silent fail caused by type missmatch?
Table 1:
CREATE TABLE [Planning].[DimStation]
(
[ID] INT PRIMARY KEY,
[DW2_TV_DimStation_Id] INT NULL,
[DW2_OTT_DimStation_Id] INT NULL,
[Name] NVARCHAR(128) NOT NULL,
[CoreTVCode] CHAR(5) NULL,
[CoreOTTCode] CHAR(10) NULL,
[StrataTVCode] CHAR(10) NULL,
[HouseHolds] DECIMAL(5,2) NULL,
[MaleSkew] DECIMAL(5,2) NULL,
[FemaleSkew] DECIMAL(5,2) NULL,
[AverageAge] INT NULL,
[AverageIncome] DECIMAL(23,2) NULL,
[BroadReach] BIT NULL,
[Description] NVARCHAR(MAX) NULL,
[Owner] NVARCHAR(128) NULL,
[Notes] NVARCHAR(MAX) NULL,
[timestamp] timestamp NOT NULL,
[CreatedOn] DATETIME2(7) CONSTRAINT [df_Planning_DimStation_CreatedOn] DEFAULT (sysutcdatetime()) NOT NULL,
[ModifiedOn] DATETIME2(7) CONSTRAINT [df_Planning_DimStation_ModifiedOn] DEFAULT (sysutcdatetime()) NOT NULL,
[Retired] BIT CONSTRAINT [df_Planning_DimStation_Retired] DEFAULT (0) NOT NULL
)
GO
Table 2:
Joining on different data types tends to yield unexpected results.
To fix this, use casts.
A note is that Access doesn't allow nulls to be cast. So we need to work around that using Nz (same as ISNULL in T-SQL) and explicitly handling nulls.
AND NOT EXISTS (
SELECT
1
FROM
DimStation AS tgt
WHERE
CLng(IIF(tgt.[ID] IS NULL, 0, tgt.ID)) = src.[ID] AND NOT tgt.ID IS NULL
);

INSERT trigger causing trouble

I'm new to writing SQL Server triggers. I have a table called USERS and I also a another tabled called USERS_DELTA. The difference between the two is USERS_DELTA has one additional column called change_type.
Here are the table schema:
USERS table:
CREATE TABLE [dbo].[TDR_Users]
(
[objectGUID] [varbinary](50) NOT NULL,
[distinguishedName] [nvarchar](255) NOT NULL,
[adForest] [nvarchar](50) NULL,
[adDomain] [nvarchar](50) NULL,
[accountExpires] [datetime] NULL,
[adminCount] [int] NULL,
[cn] [nvarchar](64) NULL,
[company] [nvarchar](64) NULL,
[description] [nvarchar](448) NULL,
[displayName] [nvarchar](256) NULL,
[division] [nvarchar](256) NULL,
[employeeID] [nvarchar](16) NULL
)
And USERS_DELTA table:
CREATE TABLE [dbo].[TDR_Users]
(
[objectGUID] [varbinary](50) NOT NULL,
[distinguishedName] [nvarchar](255) NOT NULL,
[adForest] [nvarchar](50) NULL,
[adDomain] [nvarchar](50) NULL,
[accountExpires] [datetime] NULL,
[adminCount] [int] NULL,
[cn] [nvarchar](64) NULL,
[company] [nvarchar](64) NULL,
[description] [nvarchar](448) NULL,
[displayName] [nvarchar](256) NULL,
[division] [nvarchar](256) NULL,
[employeeID] [nvarchar](16) NULL,
[change_Type] [nvarchar](10) NULL
)
I have an application which will be creating records in USERS table. But what I'm trying to do is capture the inserts into the USERS_DELTA. I have written a trigger on the USERS table:
CREATE TRIGGER [dbo].[TR_INSERTS_DELTAS]
ON [dbo].[Users]
FOR INSERT
AS
DECLARE #ObjectGUID varbinary(50), #DN varchar(255), #memcount int;
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Get the primary and unique keys from the inserted rows.
SELECT #DN=i.distinguishedName FROM inserted i;
SELECT #ObjectGUID = i.objectGUID FROM inserted i;
-- Check if a row already exists in the TDR_Users_Delta table with those values.
SELECT #memcount=COUNT(*) FROM Users
WHERE Users.distinguishedName = #DN
AND Users.objectGUID = #ObjectGUID ;
if(#memcount = 0)
BEGIN
INSERT INTO [dbo].[Users_Delta]
(
[objectGUID],
[distinguishedName],
[adForest],
[adDomain],
[accountExpires],
[adminCount],
[cn] ,
[company],
[description],
[displayName],
[division],
[employeeID],
[change_type]
)
VALUES
(
INSERTED.[objectGUID],
INSERTED.[distinguishedName],
INSERTED.[adForest],
INSERTED.[adDomain],
INSERTED.[accountExpires],
INSERTED.[adminCount],
INSERTED.[cn] ,
INSERTED.[company],
INSERTED.[description],
INSERTED.[displayName],
INSERTED.[division],
INSERTED.[employeeID],
'Add'
);
END
END
GO
When I execute this trigger, I get the following error:
Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 94
The multi-part identifier "Inserted.objectGUID" could not be bound.
Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 95
The multi-part identifier "INSERTED.distinguishedName" could not be bound.
Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 96
The multi-part identifier "INSERTED.adForest" could not be bound.
Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 97
The multi-part identifier "INSERTED.adDomain" could not be bound.
Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 98
...
What am I doing wrong? :(
I think you just need to put a select with the table in rather than using inserted.x to signify the insert.
CREATE TRIGGER [dbo].[TR_INSERTS_DELTAS]
ON [dbo].[Users]
FOR INSERT
AS
DECLARE #ObjectGUID varbinary(50), #DN varchar(255), #memcount int;
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Get the primary and unique keys from the inserted rows.
SELECT #DN=i.distinguishedName FROM inserted i;
SELECT #ObjectGUID = i.objectGUID FROM inserted i;
-- Check if a row already exists in the TDR_Users_Delta table with those values.
SELECT #memcount=COUNT(*) FROM Users
WHERE Users.distinguishedName = #DN
AND Users.objectGUID = #ObjectGUID ;
if(#memcount = 0)
BEGIN
INSERT INTO [dbo].[Users_Delta]
(
[objectGUID],
[distinguishedName],
[adForest],
[adDomain],
[accountExpires],
[adminCount],
[cn] ,
[company],
[description],
[displayName],
[division],
[employeeID],
[change_type]
)
select
INSERTED.[objectGUID],
INSERTED.[distinguishedName],
INSERTED.[adForest],
INSERTED.[adDomain],
INSERTED.[accountExpires],
INSERTED.[adminCount],
INSERTED.[cn] ,
INSERTED.[company],
INSERTED.[description],
INSERTED.[displayName],
INSERTED.[division],
INSERTED.[employeeID],
'Add'
From inserted
END
END
GO

Mysql error 1111 in one version of query and error 1054 in another

I have two tables:
books: [isbn, book_title, publisher, ...]
inventory: [isbn, date, num_changed]
I want to return book titles for those which are on stock. I tried a join (query 1) and got 1054 error, then I substituted the reference with the literal value and now I get 1111 error.
query 1:
SELECT `books`.`isbn`, `books`.`book_title`, SUM( `inventory`.`numbers_changed` ) AS `num`
FROM `books`
INNER JOIN `inventory` ON `books`.`isbn` = `inventory`.`isbn`
WHERE `books`.`publisher` LIKE '%pint%'
AND `num` > '0'
query 2:
SELECT `books`.`isbn`, `books`.`book_title`, SUM( `inventory`.`numbers_changed` )
FROM `books`
INNER JOIN `inventory` ON `books`.`isbn` = `inventory`.`isbn`
WHERE `books`.`publisher` LIKE '%print%'
AND SUM( `inventory`.`numbers_changed` ) > '0'
What's the correct query to use?
Edit
Here are the create table queries:
CREATE TABLE IF NOT EXISTS `books` (
`isbn` varchar(30) CHARACTER SET ascii NOT NULL,
`book_title` varchar(255) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`date_published` varchar(10) CHARACTER SET ascii NOT NULL,
`author` varchar(40) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`translator` varchar(40) CHARACTER SET utf8 COLLATE utf8_persian_ci DEFAULT NULL,
`publisher` varchar(50) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`ganre` varchar(50) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`price` int(7) unsigned NOT NULL,
`cover_pic` int(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`isbn`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `inventory` (
`isbn` varchar(30) CHARACTER SET ascii NOT NULL,
`date` varchar(10) CHARACTER SET ascii NOT NULL,
`numbers_changed` int(5) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
The 1054 error is about referencing a column that doesn't exist. The actual error message would help to know what is causing the issue.
The 1111 error is because you're trying to use aggregate function (in this case, SUM) in the WHERE clause:
WHERE ...
AND SUM( `inventory`.`numbers_changed` ) > '0'
^
|__ see this?
...outside of a subquery. SQL statements are checked from bottom to top, so I expect that removing the SUM in the WHERE clause will show that the 1054 error is still unaddressed.
use having for second where argument
WHERE `books`.`publisher` LIKE '%print%'
HAVING ( COUNT(`inventory`.`numbers_changed`) > '0')
instead of
WHERE `books`.`publisher` LIKE '%print%'
AND SUM( `inventory`.`numbers_changed` ) > '0'