Dynamic Variable Name for backup table - sql

I am trying to write a stored procedure to backup a table, but I keep getting:
Msg 402, Level 16, State 1, Line 9
The data types varchar and datetime2 are incompatible in the add operator.
Msg 402, Level 16, State 1, Line 15
The data types varchar and datetime2 are incompatible in the add operator.
How can I fix this?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
DECLARE #CreateDynamicSQL nvarchar(1000);
DECLARE #CopyDynamicSQL nvarchar(1000);
SET #CreateDynamicSQL='CREATE TABLE [dbo].[paul_AccountContact_Backup_'+#SYSDATETIME+'](
[AccountID] [int] NOT NULL,
[ContactID] [int] NOT NULL
) ON [PRIMARY]
GO'
SET #CopyDynamicSQL='select * into [dbo].[paul_AccountContact_Backup_'+#SYSDATETIME+'] from paul_AccountContacts'
EXEC(#CreateDynamicSQL);
EXEC(#CopyDynamicSQL);

You have to convert your date variable to a string so you can concatenate it:
SET #CreateDynamicSQL='CREATE TABLE [dbo].[paul_AccountContact_Backup_'
+ convert(varchar(20), #SYSDATETIME, <Format>) + '](
Documentation for the format parameter:
https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-2017

Related

Merge stored procedure

CREATE TABLE [dbo].[SupplierTableType](
[Supplier_ID] [nvarchar](10) NULL,
[Supplier_Name] [nvarchar](50) NULL,
[Address1] [nvarchar](30) NULL,
[Address2] [nvarchar](30) NULL,
[Address3] [nvarchar](30) NULL,
)
GO
--------------------Procedure----------------------
CREATE PROCEDURE [dbo].[Update_SupplierTable]
#TblSupplierTable SupplierTableType READONLY
AS
BEGIN
SET NOCOUNT ON;
MERGE INTO SupplierTable c1
USING #TblSupplierTable c2
ON c1.Supplier_ID=#TblSupplierTable.Supplier_ID
WHEN MATCHED THEN
UPDATE SET
c1.[Supplier_Name]= c2.[Supplier_Name]
, c1.[Address1]=c2.[Address1]
, c1.[Address2]=c2.[Address2]
, c1.[Address3]=c2.[Address3]
WHEN NOT MATCHED THEN
INSERT VALUES( #TblSupplierTable.[Supplier_Name],
c2.[Address1],
c2.[Address2],
c2.[Address3]
);
END
Msg 2715, Level 16, State 3, Procedure Update_SupplierTable, Line 3 [Batch Start Line 56]
Column, parameter, or variable #1: Cannot find data type SupplierTableType.
Parameter or variable '#TblSupplierTable' has an invalid data type.
Msg 1087, Level 16, State 1, Procedure Update_SupplierTable, Line 8 [Batch Start Line 56]
Must declare the table variable "#TblSupplierTable".
Instead of creating a table, you have to create a data type for SupplierTableType.
I.e. instead of
CREATE TABLE SupplierTableType...
you have to use
CREATE TYPE SupplierTableType AS TABLE ...
See the docs for further info.

Msg 207, Level 16, State 1 "Invalid column name 'Name'"

I'm trying to drop and recreate a table with a new schema in SQL Server, and then insert some test data into it to validate that it's working correctly. I have the following DDL:
CREATE TABLE [dbo].[Product](
[ID] int IDENTITY(1,1) PRIMARY KEY,
[Name] VARCHAR(100) NOT NULL,
[Description] VARCHAR(200) NULL,
[Modified] DATETIME NOT NULL DEFAULT(GETUTCDATE()),
[ModifiedBy] VARCHAR(32) NOT NULL
);
and the following insert statement:
INSERT INTO [dbo].[Product]([Name], [Description], [Modified], [ModifiedBy])
VALUES('Test', 'Description', GETUTCDATE(), 'Me');
Whenever I attempt to insert the aforementioned row, I get an error:
Msg 207, Level 16, State 1, Line 38
Invalid column name 'Name'.
Msg 207, Level 16, State 1, Line 38
Invalid column name 'Description'.
I know the table is there since I can SELECT * FROM Product and get an empty result set with the correct columns and no errors... I just can't insert into it for some reason. Any help would be greatly appreciated!
As per Martin's answer, I did some more research and he is correct. The schema manipulation needs to be done in separate batches (I simply added a GO after dropping my old table and after creating my new one with a different schema). A more detailed answer can be found here: "Invalid column name" error when calling insert after table created
Maybe try refreshing the cache. Easy way is to press Ctrl + shift + R
Or
Edit > IntelliSense > Refresh Local Cache
If doesnt work, then use qualified names [dbo].table or username.tablename etc
More here: http://msdn.microsoft.com/en-us/library/ms174205.aspx
For me, your query looks good, and i test it successfully.
Try adding schema name and put all column name inside brackets:
CREATE TABLE [dbo].[Product](
[ID] int IDENTITY(1,1) PRIMARY KEY,
[Name] VARCHAR(100) NOT NULL,
[Description] VARCHAR(200) NULL,
[Modified] DATETIME NOT NULL DEFAULT(GETUTCDATE()),
[ModifiedBy] VARCHAR(32) NOT NULL
);
INSERT INTO [dbo].[Product]([Name], [Description], [Modified], [ModifiedBy])
VALUES('Test', 'Description', GETUTCDATE(), 'Me');
Don't do anything just try to insert (' ')single quotes instead of (") quotes.. or if you insert data with ('')single quotes try for (") double quotes it's really helping you.

SQL Server: how to create temp table with auto increment?

I am trying to create a temp table with an auto increment and insert data. The table is created correctly, but I cannot import the data.
If I just omit the ID table it works correctly, but I need to have the temp table have an ID that we can reference.
The errors I get are:
Msg 4832, Level 16, State 1, Line 1
Bulk load: An unexpected end of file was encountered in the data file.
Msg 7399, Level 16, State 1, Line 1
The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.
My code:
SET #strFileName = 'file.txt';
SET NOCOUNT OFF;
CREATE TABLE #UUID
(
id INT NOT NULL IDENTITY PRIMARY KEY,
cuuid NVARCHAR(50) COLLATE DATABASE_DEFAULT NULL
);
SET #strSQL = 'BULK INSERT #UUIDFROM ''' + #strFileName + ''' WITH (ROWTERMINATOR =''\n'' )';
EXEC #intErr = sp_executesql #strSQL;
I wonder if it's trying to insert into the the id row instead of the cuuid row...
Any ideas?
If the problem is that you have an extra column in the database that is not in the data file, then the solution is a view. Alas, I don't think you can do this with a temp table.
With a regular table:
CREATE TABLE temp_UUID (
id INT NOT NULL IDENTITY PRIMARY KEY,
cuuid NVARCHAR(50) COLLATE DATABASE_DEFAULT NULL
);
CREATE VIEW temp_UUID_v as
SELECT cuuid
FROM temp_UUID;
SET #strSQL = 'BULK INSERT temp_UUID_V FROM ''' + #strFileName + ''' WITH ( ROWTERMINATOR =''\n'' )';
EXEC #intErr= sp_executesql #strSQL;

Stored procedure error: "Error converting data type nvarchar to uniqueidentifier"

So I'm new to creating SPs and right now I am trying to create an SP to insert values into my table Report below.
CREATE TABLE Report (
ID UNIQUEIDENTIFIER PRIMARY KEY NOT NULL,
STAFF VARCHAR(1000)NOT NULL,
EMAIL VARCHAR(1000)NOT NULL,
LASTCHANGE DATE NOT NULL
)
CREATE PROCEDURE spInsertOrUpdate(
#ID UNIQUEIDENTIFIER,
#STAFF VARCHAR(1000),
#EMAIL VARCHAR(1000),
#LASTCHANGE DATETIME
) AS
BEGIN
INSERT INTO Report(ID, STAFF, EMAIL, LASTCHANGE)
VALUES(#ID, #STAFF, #EMAIL, #LASTCHANGE)
END
EXEC spInsertOrUpdate NEWID, 'Evlyn Dawson', 'evdawson#gmail.com', GETDATE
Right After executing the SP I following error:
Msg 8114, Level 16, State 5, Procedure spInsertOrUpdate, Line 0 Error converting data type nvarchar to uniqueidentifier
Can someone please help me out with this issue?
So if your just calling your stored procedure with getdate and newid why dont you just add them as default on your table?
Table
CREATE TABLE [dbo].[Report](
[ID] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Report_ID] DEFAULT (newid()),
[STAFF] [varchar](1000) NOT NULL,
[EMAIL] [varchar](1000) NOT NULL,
[LASTCHANGE] [datetime] NOT NULL CONSTRAINT [DF_Report_LASTCHANGE] DEFAULT (getdate()),
CONSTRAINT [PK__Report__3214EC27D2D8BF72] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Procedure
create PROCEDURE spInsertOrUpdate(
#STAFF VARCHAR(1000),
#EMAIL VARCHAR(1000)
) AS
BEGIN
INSERT INTO Report(STAFF, EMAIL)
VALUES(#STAFF, #EMAIL)
END
Execute statement
EXEC spInsertOrUpdate 'Evlyn Dawson', 'evdawson#gmail.com'
Edit
Please also note that your lastchanged column is of type DATE, however if you want date with timestamp you should use datetime
This error message is a bit of a wild goose chase, the problem is that both NEWID() and GETDATE() are functions, so require parentheses. Unforunately, you cannot pass a function as a parameter to a stored procedure, so you would first need to assign the values to a variable:
DECLARE #ID UNIQUEIDENTIFIER = NEWID(),
#Date DATE = GETDATE();
EXEC #spInsertOrUpdate #ID, 'Evlyn Dawson', 'evdawson#gmail.com', #Date;
As an aside, a UNIQUEIDENTIFIER column is a very poor choice for a clustering key
I would start by calling the functions correctly:
EXEC spInsertOrUpdate NEWID(), 'Evlyn Dawson', 'evdawson#gmail.com', GETDATE();
NEWID() and GETDATE() are functions, so you need parentheses after them.
However, I don't think the lack of parentheses would cause that particular error. You would need to set variables first, and then use them for the exec.
EDIT:
A better approach is to set the ids and dates automatically:
CREATE TABLE Report (
ID UNIQUEIDENTIFIER PRIMARY KEY NOT NULL DEFAULT NEWID(),
STAFF VARCHAR(1000) NOT NULL,
EMAIL VARCHAR(1000) NOT NULL,
LASTCHANGE DATE NOT NULL DEFAULT GETDATE()
);
CREATE PROCEDURE spInsertOrUpdate (
#STAFF VARCHAR(1000),
#EMAIL VARCHAR(1000)
) AS
BEGIN
INSERT INTO Report(STAFF, EMAIL)
VALUES (#STAFF, #EMAIL)
END;
EXEC spInsertOrUpdate 'Evlyn Dawson', 'evdawson#gmail.com';
I would also discourage you from using unique identifiers as primary keys in the table. They are rather inefficient, because they can lead to page fragmentation. Use an identity column instead.
Thanks For all your help.I finally found a proper way of doing this within the SP
and I got a proper understanding of SPs now.This is how I resolved the issue
CREATE PROCEDURE spInsertOrUpdate(#STAFF VARCHAR(1000),#EMAIL VARCHAR(1000),#CARS VARCHAR(1000))
AS
BEGIN
INSERT INTO Report(ID,STAFF,EMAIL,CARS,LASTCHANGE)
VALUES(NEWID(),#STAFF,#EMAIL,#CARS,GETDATE())
END
EXEC spInsertOrUpdate 'Evlyn Dawson','evdawson#gmail.com','Ferrari'
Note that I have also a CARS column

SQL Server FUNCTION overflow int vs bigint

I am using a SQL Server function which returns a bigInt and using this in a trigger to assign a value to a column of type bigint. However when I run the trigger, an overflow exception occurs (Arithmetic overflow error converting expression to data type int.), i.e. it treats it as an int, not a bigint
The function is:
ALTER FUNCTION [dbo].[longIntDateTime] ()
RETURNS bigint
AS
BEGIN
-- Declare the return variable here
DECLARE #ResultVar bigint;
DECLARE #now Datetime;
set #now = getdate();
SET #ResultVar=DATEPART(YYYY,#now)*100000000 + DATEPART(MM,#now)*1000000 + DATEPART(DD,#now)*10000 + DATEPART(HH,#now)*100;
-- DATEPART(HH,#now)*100 + DATEPART(MI,#now);
-- Return the result of the function
RETURN (#ResultVar);
END
The trigger is:
ALTER TRIGGER [dbo].[employeesInsert]
ON [dbo].[employees]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
UPDATE employees
SET changeTimeStamp = dbo.longIntDateTime()
FROM inserted INNER JOIN employees On inserted._id = employees._id
END
and the table definition is:
CREATE TABLE [dbo].[employees](
[_id] [int] IDENTITY(1,1) NOT NULL,
[employee_name] [varchar](50) NOT NULL,
[password] [varchar](50) NOT NULL,
[isActive] [int] NOT NULL,
[isDeleted] [int] NOT NULL,
[changeTimeStamp] [bigint] NOT NULL,
CONSTRAINT [PK_employees] PRIMARY KEY CLUSTERED ([_id] ASC)
)
ALTER TABLE [dbo].[employees]
ADD CONSTRAINT [DF_employees_isActive] DEFAULT ((0)) FOR [isActive]
ALTER TABLE [dbo].[employees]
ADD CONSTRAINT [DF_employees_isDeleted] DEFAULT ((0)) FOR [isDeleted]
GO
If I take two '0's off the first yyyy part of the function, the trigger succeeds, however as is, it fails.
Clearly the value produced is less than a big int.
any ideas?
anton
The problem is this line of code:
SET #ResultVar=DATEPART(YYYY,#now)*100000000 + DATEPART(MM,#now)*1000000 + DATEPART(DD,#now)*10000 + DATEPART(HH,#now)*100;
The constants are interpreted as int so the entire calculate is done that way. You can fix this easily by casting the first to bigint:
SET #ResultVar=DATEPART(YYYY,#now)*cast(100000000 as bigint)+ DATEPART(MM,#now)*1000000 + DATEPART(DD,#now)*10000 + DATEPART(HH,#now)*100;
It's because DATEPART returns int.Try to cast to bigint before multiplying
cast (DATEPART(YYYY,#now) as bigint)*100000000