sql error in visual studio - sql-server

why I am getting the following error?
Error 11 SQL71006: Only one statement is allowed per batch. A batch
separator, such as 'GO', might be required between
statements. dbo.Table_1 1 1
Here is my code:
IF OBJECT_ID('Database1') IS NOT NULL
DROP TABLE Table_1;
CREATE TABLE [dbo].[Table]
(
[departament] VARCHAR(MAX) NOT NULL PRIMARY KEY,
[specializare] VARCHAR(MAX) NOT NULL,
[student] VARCHAR(MAX) NOT NULL,
[profesor] VARCHAR(MAX) NOT NULL
)

You are missing a GO between the Statements.
IF OBJECT_ID('Database1') IS NOT NULL
DROP TABLE Table_1;
GO
CREATE TABLE [dbo].[Table]
(
[departament] VARCHAR(MAX) NOT NULL PRIMARY KEY,
[specializare] VARCHAR(MAX) NOT NULL,
[student] VARCHAR(MAX) NOT NULL,
[profesor] VARCHAR(MAX) NOT NULL
)

Related

SQL Server : how to create tables in stored procedures?

Task: write a SQL script to build a table. Call the script spCreateTable(), it should accept one argument, a varchar called subjectOfTable.
subjectOfTable is a varchar containing the subject of the table. Some examples are example “Employee” or “Formula.” Your script will use that subject to build the table name, primary key, and natural key.
For example, given “Employee” as the subject, your script will build a table called tEmployee with a surrogate key called EmployeeID and a natural key called Employee. Be sure to create the necessary constraints for the keys.
CREATE PROCEDURE [dbo].[sp_CreateTable]
#subjectOfTable VARCHAR(30)
AS
BEGIN
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID (#tabName) AND type in (N'U'))
DROP TABLE [dbo].[#tabName]
CREATE TABLE #tabName
(
[ID] [INT] IDENTITY(1,1) NOT NULL,
[RankID] [INT] NOT NULL,
[SlotTime] [NVARCHAR](10) NOT NULL,
[SlotDate] [NVARCHAR](30) NOT NULL
) ON [PRIMARY]
END
This is what I have so far, any help would be great. Thanks!
You can create the table with a generic name, and then use the sp_rename stored procedure to rename it to the variable name:
CREATE TABLE IF EXISTS sp_CreateTable_TempTable (
[ID] [int] IDENTITY(1,1) NOT NULL,
[RankID] [int] NOT NULL,
[SlotTime] [nvarchar](10) NOT NULL,
[SlotDate] [nvarchar](30) NOT NULL
) ON [PRIMARY]
GO
EXEC sp_rename sp_CreateTable_TempTable, #subjectOfTable;
GO
Since I cannot comment, I'll just throw it out here
What's the real usage of this code anyway? to create table often but same with columns?
I don't know how other person will run this (in SSMS? in application?)
FYI SSMS also has Template for create table (Ctrl+Alt+T), then he/she can press Ctrl+Shift+M to fill in the parameters every time.
If the columns are fixed, you can customize first and send it to them so they only change the part
-- =========================================
-- Create table template
-- =========================================
USE <database, sysname, AdventureWorks>
GO
IF OBJECT_ID('<schema_name, sysname, dbo>.<table_name, sysname, sample_table>', 'U') IS NOT NULL
DROP TABLE <schema_name, sysname, dbo>.<table_name, sysname, sample_table>
GO
CREATE TABLE <schema_name, sysname, dbo>.<table_name, sysname, sample_table>
(
<columns_in_primary_key, , c1> <column1_datatype, , int> <column1_nullability,, NOT NULL>,
<column2_name, sysname, c2> <column2_datatype, , char(10)> <column2_nullability,, NULL>,
<column3_name, sysname, c3> <column3_datatype, , datetime> <column3_nullability,, NULL>,
CONSTRAINT <contraint_name, sysname, PK_sample_table> PRIMARY KEY (<columns_in_primary_key, , c1>)
)
GO
first: prefixing a stored procedure should be usually avoided
you can use dynamic sql like that: (but better read that before)
BEGIN TRAN;
GO
CREATE PROCEDURE [dbo].[CreateTable]
( #Tabname SYSNAME
, #SchemaName NVARCHAR(128) = NULL
) AS
BEGIN;
SET #SchemaName = ISNULL (#SchemaName, N'dbo');
IF ( SELECT object_id (#SchemaName + N'.'+#tabname ) ) IS NOT NULL
EXEC ( N'DROP TABLE ' + #SchemaName + N'.'+#tabname)
EXEC (N'CREATE TABLE ' + #SchemaName + N'.'+#tabname + N'
( [ID] [INT] IDENTITY(1,1) NOT NULL,
[RankID] [INT] NOT NULL,
[SlotTime] TIME NOT NULL,
[SlotDate] DATE NOT NULL
) ON [PRIMARY]'
);
RETURN 0;
END;
GO
SELECT OBJECT_ID (N'dbo.test') AS OBJECT_ID
EXEC [dbo].[CreateTable] #tabname = test
SELECT OBJECT_ID (N'dbo.test') AS OBJECT_ID
ROLLBACK

Couldn't drop and recreate the table if exist on SQL Server

Expecting to drop and re-create if the table is exist. Actual is instead of dropping the table, inserting data again on to the table.
BEGIN
PRINT N'Seeding [Proj].[UserTable]...';
SET NOCOUNT ON
--
-- BEGIN SEED DATA SECTION
--
IF OBJECT_ID('#tempdb..#SeedData') IS NOT NULL DROP TABLE #SeedData
SET NOCOUNT ON
CREATE TABLE #SeedData (
[UserName] nvarchar(50) NULL,
[CreatedById] [bigint] NULL,
[CreatedDate] [datetimeoffset](7) NULL
)
INSERT INTO #SeedData SELECT N'UserA',-1,getdate()
...
--
-- END SEED DATA SECTION
--
SET NOCOUNT OFF
INSERT INTO [Proj].[UserTable] (
[UserName],
[CreatedById],
[CreatedDate]
)
SELECT seed.[UserName]
,seed.[CreatedById]
,seed.[CreatedDate]
FROM #SeedData seed
DROP TABLE #SeedData
SET NOCOUNT OFF
END
GO
Tried codes:
- IF OBJECT_ID('#SeedData', 'U') IS NOT NULL DROP TABLE #SeedData
- IF OBJECT_ID('tempdb..#SeedData', 'U') IS NOT NULL DROP TABLE #SeedData
use
IF OBJECT_ID('tempdb..#SeedData') is not null
drop table #seeddata
I am not able to repro the issue,even passing the table parameter..
Test :
create table #test
(
id int
)
select * from tempdb.sys.objects--you can see table
if object_id('tempdb..#test','u') is not null
drop table #test
select * from tempdb.sys.objects--you can't see table
Remove the hash in front of '#temp db..'
BEGIN
PRINT N'Seeding [Proj].[UserTable]...';
SET NOCOUNT ON
--
-- BEGIN SEED DATA SECTION
--
IF OBJECT_ID('tempdb..#SeedData') IS NOT NULL DROP TABLE #SeedData
SET NOCOUNT ON
CREATE TABLE #SeedData (
[UserName] nvarchar(50) NULL,
[CreatedById] [bigint] NULL,
[CreatedDate] [datetimeoffset](7) NULL
)
INSERT INTO #SeedData SELECT N'UserA',-1,getdate()
...
--
-- END SEED DATA SECTION
--
SET NOCOUNT OFF
INSERT INTO [Proj].[UserTable] (
[UserName],
[CreatedById],
[CreatedDate]
)
SELECT seed.[UserName]
,seed.[CreatedById]
,seed.[CreatedDate]
FROM #SeedData seed
DROP TABLE #SeedData
SET NOCOUNT OFF
END
GO
Try this instead for the drop table statement, replacing [Database].[Schema].[TableName] for the object you're trying to drop.
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[Database].[Schema].[TableName]') AND type in (N'U'))
DROP TABLE [Database].[Schema].[TableName]
GO

MSSQL DateTime2 Fail to Update

Im running stored procedure which in charges to insert, update and delete table's entries.
While both insert and delete runs smoothly, the update operation updates all columns except DATETIME2 one.
The scenario - I test my Repository pattern (using C# code) in the following way:
delete the entire [BackgroundTaskAttachtment] table
Create 4 new entries
delete single entry created on step 2
Wait for 5 seconds
modify one of the entries
the result is having 3 entries in [BackgroundTaskAttachtment] table, with all properties set as expected, except the [UpdatedOnUtc] which not updated (it is equal to [CreatedOnUtc]
I marked the updated row (as you can see [FilePath] was successfully updated):
Would appreciate community insights,
Thank you
This is the stored procedure code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_ArrangeBackgroundTaskAttachtments]
(
#backgroundTaskId BIGINT,
#taskAttchs [dbo].[BackgroundTaskAttachtmentType] READONLY
)
AS
BEGIN
SET NOCOUNT ON;
--delete all removed attachtments
DELETE FROM [BackgroundTaskAttachtment]
WHERE [BackgroundTaskId] = #backgroundTaskId AND [Id] NOT IN (SELECT [Id] FROM #taskAttchs)
----Update exist key-value pairs
UPDATE [dbo].[BackgroundTaskAttachtment]
SET
[IsPrimary] = attachs.[IsPrimary],
[FilePath] = attachs.[FilePath],
[Bytes] = attachs.[Bytes],
[UpdatedOnUtc] = GETUTCDATE()
FROM #taskAttchs AS attachs
WHERE attachs.[Id] = [BackgroundTaskAttachtment].[Id]
--insert new records
SELECT #backgroundTaskId AS [BackgroundTaskId], [FilePath], [IsPrimary], [Bytes], GETUTCDATE() AS [CreatedOnUtc], GETUTCDATE() AS [UpdatedOnUtc]
INTO #Temp FROM #taskAttchs as atcs
WHERE atcs.[Id] NOT IN (SELECT [Id] FROM [BackgroundTaskAttachtment] AS bta WHERE bta.[BackgroundTaskId] = #backgroundTaskId )
INSERT INTO [BackgroundTaskAttachtment]([BackgroundTaskId], [IsPrimary], [Bytes], [FilePath], [CreatedOnUtc], [UpdatedOnUtc] )
SELECT [BackgroundTaskId], [IsPrimary], [Bytes], [FilePath], [CreatedOnUtc], [UpdatedOnUtc]
FROM #Temp
END
This is the table type (sent from CLR to SQL)
CREATE TYPE [dbo].[BackgroundTaskAttachtmentType] AS TABLE(
[Id] [BIGINT] NOT NULL,
[FilePath] [NVARCHAR](MAX) NULL,
[IsPrimary] [BIT] NOT NULL,
[BackgroundTaskId] [BIGINT] NULL,
[Bytes] [VARBINARY](MAX) NULL
)
GO
this is the table definition
CREATE TABLE [dbo].[BackgroundTaskAttachtment]
(
[Id] BIGINT IDENTITY(1,1) NOT NULL,
[BackgroundTaskId] BIGINT NOT NULL,
[IsPrimary] BIT NOT NULL DEFAULT 0,
[FilePath] NVARCHAR(MAX) NULL,
[Bytes] VARBINARY(MAX) NULL,
[CreatedOnUtc] DATETIME2 NOT NULL,
[UpdatedOnUtc] DATETIME2 NOT NULL,
[RowVersion] ROWVERSION NOT NULL,
CONSTRAINT [PK_dbo.BackgroundTaskAttachtment] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.BackgroundTaskAttachtment_BackgroundTask_Id]
FOREIGN KEY ([BackgroundTaskId])
REFERENCES [dbo].[BackgroundTask] ([Id])
ON DELETE CASCADE
);
Please try using SYSUTCDATETIME which returns datetime2.
The GETUTCDATE which you are using, returns datetime.

sql server stored procedure check if exists table in other database and rename it

Have 2 databases: MAIN and IP2LOCATION
in MAIN, I have the following stored procedure:
CREATE PROCEDURE dbo.Update_IP2Location_DB11_from_CSV
AS
BEGIN
IF NOT EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[ip2location].[dbo].[db11_new]') AND type in (N'U'))
BEGIN
CREATE TABLE [ip2location].[dbo].[db11_new]
(
[ip_from] bigint NOT NULL,
[ip_to] bigint NOT NULL,
[country_code] nvarchar(2) NOT NULL,
[country_name] nvarchar(64) NOT NULL,
[region_name] nvarchar(128) NOT NULL,
[city_name] nvarchar(128) NOT NULL,
[latitude] float NOT NULL,
[longitude] float NOT NULL,
[zip_code] nvarchar(30) NOT NULL,
[time_zone] nvarchar(8) NOT NULL,
) ON [PRIMARY]
CREATE INDEX [ip_from] ON [ip2location].[dbo].[db11_new]([ip_from])
END
ELSE
BEGIN
DELETE FROM [ip2location].[dbo].[db11_new]
END
BULK INSERT [ip2location].[dbo].[db11_new]
FROM 'D:\IP2LOCATION-LITE-DB11.CSV'
WITH
( FORMATFILE = 'C:\inetpub\wwwroot\ws\DB11_ip4.FMT')
EXEC sp_rename N'dbo.db11', N'db11_old', 'OBJECT'
EXEC sp_rename N'ip2location.dbo.db11_new', N'db11', 'OBJECT'
END
that does not work properly:
if db11_new does not exists, it (correctly) creates it, but if it exists.. I get
There is already an object named 'db11_new' in the database.
therefore it seems there is something wrong in
IF NOT EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[ip2location].[dbo].[db11_new]') AND type in (N'U'))
and also at the end of procedure with the 2 Rename I get (always) the following answer
Msg 15248, Level 11, State 1, Procedure sp_rename, Line 359
Either the parameter #objname is ambiguous or the claimed #objtype (OBJECT) is wrong.
it seems problem is because the sproc is not stored into ip2location DB but in another database..
can suggest a solution, considering that I would prefer to keep all sprocs in MAIN DB, since have all other there?
Thanks
therefore it seems there is something wrong in
IF NOT EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[ip2location].[dbo].[db11_new]') AND type in (N'U'))
Your analysis is correct. The sys.objects catalog view will return objects in the current database context (MAIN). Although you could just use a 3-part name (ip2location.sys.objects), I suggest you simply check for a NULL OBJECT_ID function result:
IF OBJECT_ID(N'[ip2location].[dbo].[db11_new]', 'U') IS NULL
BEGIN
CREATE TABLE [ip2location].[dbo].[db11_new]
(
[ip_from] bigint NOT NULL,
[ip_to] bigint NOT NULL,
[country_code] nvarchar(2) NOT NULL,
[country_name] nvarchar(64) NOT NULL,
[region_name] nvarchar(128) NOT NULL,
[city_name] nvarchar(128) NOT NULL,
[latitude] float NOT NULL,
[longitude] float NOT NULL,
[zip_code] nvarchar(30) NOT NULL,
[time_zone] nvarchar(8) NOT NULL,
) ON [PRIMARY];
CREATE INDEX [ip_from] ON [ip2location].[dbo].[db11_new]([ip_from]);
END;
ELSE
BEGIN
DELETE FROM [ip2location].[dbo].[db11_new];
END;
sys.objects and sp_rename are local objects.
Try to use this:
IF NOT EXISTS (SELECT * FROM ip2location.sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[db11_new]') AND type in (N'U'))
and
EXEC ip2location.sp_rename N'dbo.db11_new', N'db11', 'OBJECT'
Maybe it helps...
Alternatively, when you wanna do things in another database than the current one, you can write you code in dynamic sql and then execute it directly in the other database.
https://msdn.microsoft.com/en-us/library/ms188001.aspx
I have tested this query (without csv upload)
At first I remove every reference to ip2location:
CREATE PROCEDURE dbo.Update_IP2Location_DB11_from_CSV
AS
BEGIN
IF NOT EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'dbo.db11_new') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[db11_new]
(
[ip_from] bigint NOT NULL,
[ip_to] bigint NOT NULL,
[country_code] nvarchar(2) NOT NULL,
[country_name] nvarchar(64) NOT NULL,
[region_name] nvarchar(128) NOT NULL,
[city_name] nvarchar(128) NOT NULL,
[latitude] float NOT NULL,
[longitude] float NOT NULL,
[zip_code] nvarchar(30) NOT NULL,
[time_zone] nvarchar(8) NOT NULL,
) ON [PRIMARY]
CREATE INDEX [ip_from] ON [dbo].[db11_new]([ip_from])
END
ELSE
BEGIN
DELETE FROM [dbo].[db11_new]
END
BULK INSERT [dbo].[db11_new]
FROM 'D:\IP2LOCATION-LITE-DB11.CSV'
WITH
( FORMATFILE = 'C:\inetpub\wwwroot\ws\DB11_ip4.FMT')
EXEC sp_rename N'dbo.db11', N'db11_old', 'OBJECT'
EXEC sp_rename N'dbo.db11_new', N'db11', 'OBJECT'
END
GO
First run:
I have no db11* tables. Execution brings me:
Msg 15248, Level 11, State 1, Procedure sp_rename, Line 401 [Batch
Start Line 2] Either the parameter #objname is ambiguous or the
claimed #objtype (OBJECT) is wrong. Caution: Changing any part of an
object name could break scripts and stored procedures.
That means that db11_new was created, and than renamed in db11, but db11_old wasn't found, so I got this error. I get db11 table in my DB.
Second run:
Caution: Changing any part of an object name could break scripts and
stored procedures. Caution: Changing any part of an object name could
break scripts and stored procedures.
That means all was created and renamed.
Third run:
Msg 15335, Level 11, State 1, Procedure sp_rename, Line 509 [Batch
Start Line 2] Error: The new name 'db11_old' is already in use as a
OBJECT name and would cause a duplicate that is not permitted. Msg
15335, Level 11, State 1, Procedure sp_rename, Line 509 [Batch Start
Line 2] Error: The new name 'db11' is already in use as a OBJECT name
and would cause a duplicate that is not permitted.
So every next re-run You will get this same errors.
My suggestion is to do something about db11_old.
Thanks to Reboon and Dan Guzman here the solution, little improved:
CREATE PROCEDURE dbo.spA_Update_IP2Location_DB11_from_CSV
AS
BEGIN
IF OBJECT_ID(N'[ip2location].[dbo].[db11_new]', 'U') IS NULL
BEGIN
CREATE TABLE [ip2location].[dbo].[db11_new](
[ip_from] bigint NOT NULL,
[ip_to] bigint NOT NULL,
[country_code] nvarchar(2) NOT NULL,
[country_name] nvarchar(64) NOT NULL,
[region_name] nvarchar(128) NOT NULL,
[city_name] nvarchar(128) NOT NULL,
[latitude] float NOT NULL,
[longitude] float NOT NULL,
[zip_code] nvarchar(30) NOT NULL,
[time_zone] nvarchar(8) NOT NULL,
) ON [PRIMARY]
CREATE INDEX [ip_from] ON [ip2location].[dbo].[db11_new]([ip_from]) ON [PRIMARY]
END
ELSE
BEGIN
delete from [ip2location].[dbo].[db11_new]
END
BULK INSERT [ip2location].[dbo].[db11_new]
FROM 'D:\IP2LOCATION-LITE-DB11.CSV'
WITH
( FORMATFILE = 'C:\inetpub\wwwroot\ws\DB11_ip4.FMT' )
BEGIN TRANSACTION
EXEC ip2location.dbo.sp_rename N'dbo.db11', N'db11_old'
EXEC ip2location.dbo.sp_rename N'dbo.db11_new', N'db11'
IF OBJECT_ID(N'[ip2location].[dbo].[db11_old]', 'U') IS NOT NULL
BEGIN
DROP TABLE ip2location.dbo.db11_old
END
COMMIT TRANSACTION
END

Alter scalar function in SQL server 2008 that referring in the computed column of a table

I have created a scalar function in SQL Server 2008 and the same I am referring in a computed column in few of my tables. Now I want to alter the function without dropping the table. But it throws an error:
Cannot ALTER 'dbo.GetStatus' because it is being referenced by object
'Order'.
Is is possible to alter the function? Or do I drop and create all dependable table first and then alter the function?
Here is my function:
CREATE FUNCTION [dbo].[GetStatus]
(
#FromDate datetime,
#ToDate datetime
)
RETURNS tinyint
AS
BEGIN
declare #ret tinyint;
if(#FromDate<=GETDATE() and (#ToDate>=GETDATE() or #ToDate is null))
set #ret= 1
else
set #ret= 0
return #ret
END
And it is referring in a table:
CREATE TABLE [dbo].[Order](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](200) NOT NULL,
[EffectiveFromDate] [datetime] NOT NULL,
[EffectiveToDate] [datetime] NULL,
[Status] AS ([dbo].[GetStatus]([EffectiveFromDate],[EffectiveToDate]))
)
This is by design. You should first drop all defaults/constraints, then alter your function and the add those constraints back. No need to drop the tables.
But you can work around this by the following trick:
add intermediate function that will call your actual function;
alter computed columns to call intermediate function instead of actual.
Example:
CREATE FUNCTION dbo.fnActual ( #p INT )
RETURNS INT
AS
BEGIN
RETURN #p + 1
END
GO
CREATE FUNCTION dbo.fnIntermediate ( #p INT )
RETURNS INT
AS
BEGIN
RETURN dbo.fnActual(#p)
END
GO
CREATE TABLE TestTable(id INT, fn AS dbo.fnIntermediate(id))
GO
Insert some value:
INSERT INTO dbo.TestTable VALUES ( 1 )
SELECT * FROM dbo.TestTable --selects 2
--throws exception
ALTER FUNCTION dbo.fnIntermediate ( #p INT )
RETURNS INT
AS
BEGIN
RETURN dbo.fnActual(#p)
END
GO
--succseeds
ALTER FUNCTION dbo.fnActual ( #p INT )
RETURNS INT
AS
BEGIN
RETURN #p + 2
END
GO
SELECT * FROM dbo.TestTable --selects 3
ALTER TABLE [dbo].[Order]
DROP COLUMN [Status]
GO
ALTER FUNCTION [dbo].[GetStatus] ...
GO
ALTER TABLE [dbo].[Order]
ADD [Status] AS ([dbo].[GetStatus]([EffectiveFromDate],[EffectiveToDate]))
GO
or even
ALTER TABLE [dbo].[Order]
DROP COLUMN [Status]
GO
ALTER TABLE [dbo].[Order]
ADD [Status] AS CAST(CASE WHEN [EffectiveFromDate] <= GETDATE() AND ([EffectiveToDate] >= GETDATE() OR [EffectiveToDate] IS NULL) THEN 1 ELSE 0 END as tinyint)
GO

Resources