SQL, cursor for one time initialization, Must declare scalar variable - sql-server

I am using a cursor to one time populate a table with all tenants that are in the tenants table. I want to make sure that the tenantId will be set with a name of General in my navigations table. But for some reason it thinks that my variable isn't set.
I tried the following code
**** Script for SelectTopNRows command from SSMS ******/
declare #tenantId int
declare #tenantName nvarchar(100)
DECLARE tenantCursor CURSOR FOR
SELECT Id, [Name]
FROM [dbo].[Tenant]
OPEN tenantCursor;
FETCH NEXT FROM tenantCursor INTO #tenantId, #tenantName;
WHILE ##FETCH_STATUS = 0
BEGIN
print #tenantId
print #tenantName
SET #tenantId = #tenantId
Insert INTO [dbo].Navigations ([Name, TenantId])
VALUES ('Algemeen', #tenantId);
GO
FETCH NEXT FROM tenantCursor INTO #tenantId, #tenantName;
END;
CLOSE tenantCursor;
DEALLOCATE tenantCursor;
GO
I got the follwoing error:
Msg 102, Level 15, State 1, Line 22
Incorrect syntax near ';'.
Msg 137, Level 15, State 2, Line 26
Must declare the scalar variable "#tenantId".
The structure of my tables
Any help will be much appreciated.
Rodney

The simple solution is to just use SQL in the set based manner with which it is designed and run the following instead of your cursor:
insert into dbo.Navigations ([Name]
,TenantId
)
select 'Algemeen'
,Id
from dbo.Tenant;
Outside of the above however, you shouldn't have a go in the middle of your cursor and you have missed some square brackets on your insert:
Insert INTO [dbo].Navigations ([Name, TenantId])
should be
Insert INTO [dbo].Navigations ([Name], [TenantId])

Related

How to create multiple tables and stored procedures in a single stored procedure

I'm trying to create a stored procedure that can create multiple tables and stored procedures, but I get a bunch of errors that incorrect syntax near GO
I'm working on a C# method to call the stored procedure.
My stored procedure is something like
CreateTables #name nvarchar(500)
declare #query nvarchar(MAX) =
'use db1
GO
create table '+#name+'_TableA(column1 int, column2 nvarchar(300)) on [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
create table '+#name+'_TableB(column1 nvarchar(500), column2 nvarchar(350)) on [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
use db2
GO
create table '+#name+'_TableC(column1 int, column2 nvarchar(300)) on [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
create table '+#name+'_TableD(column1 nvarchar(500), column2 nvarchar(350)) on [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
create procedure '+#name+'_spA #variable1 int, #variable2 nvarchar(300) as
begin
insert into tableA.....
end
GO
'
exec #query
Is this the correct way to do it?
Alternatively I was thinking of executing every create statement on its own in the stored procedure, but then I need to get the result of each one and save it to a temporal table and then return at the end.
Another route is to hardcode the create statements into my C# and execute each create query from my code, but my ideal solution is to execute everything in a single run of SQL, and get a single result set.
We currently just execute these queries by hand, but we want to automate the process.
Additionally, these are the errors I'm getting
Msg 102, Level 15, State 1, Line 16
Incorrect syntax near 'GO'.
Msg 102, Level 15, State 1, Line 26
Incorrect syntax near 'GO'.
....
Msg 111, Level 15, State 1, Line 106
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
Msg 134, Level 15, State 1, Line 122
The variable name '#variable1' has already been declared. Variable names must be unique within a query batch or stored procedure.
Dynamic queries are treated as single batch, so GO is not allowed there, but it conflicts the rule that CREATE object must be the first statement of batch.
Trying to use nested EXEC to circumvent the GO problem, if your requirement intends to put everything in a single variable:
declare #v varchar(max) =
'EXEC(''CREATE PROC dbo.test_sp1 AS'')
EXEC(''CREATE PROC dbo.test_sp2 AS'')
'
EXEC #v

Incorrect syntax near the keyword “AS” when alter trigger

i created trigger called trgInsteadofdeleteEmp
and i just want to alter it, i wrote the following SQL code
alter trigger trgInsteadofdeleteEmp on Emp
instead of delete
as
begin
declare #id int , #name nvarchar(100)
select #id =id from deleted
select #name = name from deleted
insert into EmployeeAudit values (#id ,#name + 'tried to delete at' + GETDATE() as varchar(50))
end
and have the following output:
Msg 156, Level 15, State 1, Procedure trgInsteadofdeleteEmp, Line 8 Incorrect syntax near the keyword 'as'.
can someone point me in the direction of how to find the error
Thanks.
No, no, no, no, no.
Don't make the mistake of assuming that inserted and deleted have only one row. You are just putting errors in your code that are going to pop up at an unexpected time. I actually wish that SQL Server flagged this usage when creating the trigger.
Instead:
alter trigger trgInsteadofdeleteEmp on Emp
instead of delete
as
begin
insert into EmployeeAudit(id, name)
select id,
name + ' tried to delete at ' + convert(varchar(255), GETDATE(), 121) )
from deleted d;
end;
Your error is caused by the as. There seems to be a missing cast() function. But that is not the right fix. With date/times, use convert() or format() along with the desired format.
Other suggestions:
Always include the column names when doing an insert. In fact, an audit table really should have an identity id column, createdBy, and createdAt columns, all with default values.
Look at the strings that will be produced and be sure they are readable.
Use semicolons to end statements.
Don't rely on default formatting for date/time values.

TSQL insert exec(#command)

I am wondering why below statement is not working:
insert into #temp (ip, ping) values ('ip', exec xp_cmdshell 'ping ip')
I would like to get resultset where I will have ip address in one column and ping from that server. Above query returns errors:
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'exec'.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ')'.
Thanks in advance for explanations.
You can't execute anything in a INSERT statement value list. You need to execute like this:
insert into #temp
execute xp_cmdshell 'ping ip'
[This assumes that the #temp table has a column structure matching the resultset of xp_cmdshell ]
You can also create an intermediate temp table to contain all the columns that the stored procedure returns and then insert just the ones you want into your final table.
Well, insert ... exec is notoriously inflexible. For one thing, it won't work with a values clause. Even more annoyingly, it does not support a column list. The columns in the table have to match the output of the stored procedure exactly.
The only way to use insert ... exec is:
insert TableName exec(...)
-- ^^^--> no column list!
Here's an example:
if exists (select * from tempdb.sys.tables where name like '#temp__%')
drop table #temp
create table #temp (output varchar(max))
insert into #temp execute xp_cmdshell 'ping pong'
select * from #temp

sql script needs if statement wrapped

i'm trying to wrap a simple function within an a check for existence why am i getting incorrect syntax?
updated:
GO
IF EXISTS (SELECT TOP 1 * FROM Customers)
BEGIN
USE [rstestDB]
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE FUNCTION [dbo].[udf_GetName]
(
#p1 nvarchar(25)
)
RETURNS varchar
AS
BEGIN
DECLARE #Result varchar(25)
SELECT #Result = 'John Doe'
RETURN #Result
END
END
GO
Getting following error:
Msg 156, Level 15, State 1, Line 10
Incorrect syntax near the keyword 'FUNCTION'.
Msg 178, Level 15, State 1, Line 19
A RETURN statement with a return value cannot be used in this context.
GO is a batch separator.
GO is a command recognized by the sqlcmd and osql utilities that send commands to the SQL engine, it's not valid SQL.
Take out all the GOs except for at the very end.
A simpler example that will also fail:
IF 1=1
BEGIN
SELECT 'FOO'
GO
END
All your settings should really be at the very beginning of the script since they will persist for the length of the session.

Trouble with this simple trigger script

create trigger personInsertTrigger on dbo.Person for INSERT
as
declare tmpPersonID INT
set tmpPersonID = (select ID from INSERTED)
insert into dbo.PersonRecords values (tmpPersonID, now())
I get the following error:
Msg 155, Level 15, State 2, Procedure
personInsertTrigger, Line 3 'INT' is
not a recognized CURSOR option. Msg
195, Level 15, State 10, Procedure
personInsertTrigger, Line 6 'now' is
not a recognized built-in function
name.
Can anyone help me complete this little script? I want it to save the Person's ID and the time it was inserted into a second table called PersonRecords.
Thanks.
use # for variables -
declare #tmpPersonID INT
Local variables must begin with #. Cursors don't use the # notation, so it is interpreting your declare as a cursor not a variable.
Also instead of now() I think you need to use getdate()
The variable needs to start with an #
Change
declare tmpPersonID INT
to
declare #tmpPersonID INT
Have a look at
DECLARE #local_variable (Transact-SQL)

Resources