sql script needs if statement wrapped - sql-server

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.

Related

SQL, cursor for one time initialization, Must declare scalar variable

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])

T-Sql what's wrong with this

I'm actually an ORACLE-guy. But I now I have to create a simple function in T-SQL (customer uses SQL-Srv 2008, no chance upgrading)
error message:
Msg 156, Level 15, State 1, Procedure create_view, Line 9
Incorrect syntax near the keyword 'view'.
so? what's wrong with this create view stmt?
create function create_view (#tab_name varchar(64))
returns int
as
begin
declare
#error int
;
begin
create view [dbo].[target_list]
as select * from #tab_name
;
set #error=##ERROR
return #error
end
end
thx in advance
In SQL Server, function is allow only SELECT statement. Function does not support DML and DDL statements. Reference
DML Statments includes INSERT,UPDATE,DELETE
DDL Statement includes CREATE,DROP

Syntax errors returned when attempting to use GO inside sp_MSforeachDB, NULL errors returned when attempting to remove it

I'm trying to develop a script which, when run, will drop all users beginning with the prefix "COMPANY\" that do not belong to a list of pre-authorized users. This script will be run to periodically sweep the servers of former employee DB user accounts. For testing purposes, the script below only prints the name of the unauthorized users, instead of dropping them. I need to do this for each DB on the server instance, so I am using sp_MSforeachDB. However, when I run the script, I get multiple errors, all with the same message:
Error in this script.
Msg 102, Level 15, State 1, Line 57
Incorrect syntax near 'GO'.
When I attempt to run the script outside of sp_MSforeachDB, the script works fine. So, it is obvious to me that the issue is with executing the GO statement inside sp_MSforeachDB.
I found in another post that GO is not a T-SQL command and that is why it is throwing this error when it is inside sp_MSforeachDB, but if I attempt to remove GO, several NULL errors are returned to me instead of the error above:
Error in this script.
Msg 50000, Level 15, State 1, Line 51
Error Number: (null), Severity: (null), State: (null), Line: (null),
(null)
This error is also returned if I run the GO-less statement normally (not inside sp_MSforeachDB). If I remove all error handling in the script, it works fine, but I do need to have error handling in this script.
So...I'm a bit lost as to how to make this work. Admittedly, I am pretty new to error handling in T-SQL and was working off of an example, so there may be something obvious I am missing. Ideas? Are there good alternatives to sp_MSforeachDB that don't use stored procedures at all which would work with this? Any and all help is appreciated.
Script is below. You can remove GOTO BAGIT and BAGIT: GO to see the NULL errors.
EXECUTE master.sys.sp_MSforeachdb
'USE [?];
/* Declare error-handling variables */
DECLARE #err_no int, #err_severity int, #err_state int, #err_line int, #err_message varchar(4000)
DECLARE #nrows int
/* First pull in list of users who have a COMPANY user name but are not in list of approved users */
DECLARE #Fetch_UsersList_Status INT;
DECLARE #ExecuteSQL_UsersList VARCHAR(2500);
DECLARE #NextUser VARCHAR(250);
DECLARE UsersList CURSOR FOR
SELECT name FROM sys.database_principals
where
name LIKE ''COMPANY\%''
AND
name NOT IN (''COMPANY\User1'',''COMPANY\User2'',''COMPANY\User3'',''COMPANY\User4'',''COMPANY\User5'')
OPEN UsersList
FETCH NEXT FROM UsersList INTO #NextUser
/* Use local variable to store UsersList FETCH_STATUS. This will be used as the condition for the USERDROP WHILE loop */
SET #Fetch_UsersList_Status = ##FETCH_STATUS
/* USERDROP WHILE Loop */
BEGIN TRY
WHILE #Fetch_UsersList_Status = 0
BEGIN
PRINT #NextUser
FETCH NEXT FROM UsersList INTO #NextUser
SET #Fetch_UsersList_Status = ##FETCH_STATUS
END
END TRY
BEGIN CATCH
SELECT #err_no=ERROR_NUMBER(), #err_severity=ERROR_SEVERITY(), #err_state=ERROR_STATE(),
#err_line=ERROR_LINE(), #err_message=ERROR_MESSAGE()
GOTO ERROR_EXIT
END CATCH
CLOSE UsersList
DEALLOCATE UsersList
GOTO BAGIT
ERROR_EXIT:
DECLARE #newline char(1)
SET #newline = CHAR(10)
PRINT ''Error in this script.''
RAISERROR(''Error Number: %d, Severity: %d, State: %d, Line: %d, %s%s'', 15, 1,
#err_no, #err_severity, #err_state, #err_line, #newline, #err_message) WITH LOG
BAGIT:
GO
'

Error with the below script

I am performing the below operation. I am getting the error and unable to find what the error is.Could any one help me finding it.
a) Check for the availability of DESTINATION data base. If it is not exist, create the data base and move the tables to the data base.
b) If the table exists in the DESTINATION data base then no process required for the table.
if db_id('Destination')is null
begin
Create database Destination
select * into TabDestination from [Source].[dbo].[TabSource]
end
else
begin
use Destination
go
if('TabDestination' in (select name from sys.objects where type = 'u'))
insert into TabDestination select * from [Source].[dbo].[TabSource]
end
I am getting fallowing error
Msg 911, Level 16, State 1, Line 8
Database 'Destination' does not exist. Make sure that the name is entered correctly.
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'end'.
Your problem is with the USE, from the documentation:
USE is executed at both compile and execution time...
If the database specified doesn't exist at compile time then the query will fail. You can see this by trying to run the following query:
IF 1 = 2
BEGIN
USE NonexistantDatabase
END
This query fails despite the fact that the USE statement is never executed.
You should instead change your query to use database qualified names, for example:
INSERT INTO Destination.dbo.Table SELECT * FROM Source.dbo.Table
Few problems here:
After Create database Destination you need to use that database before you do the select * into TabDestination... as you will create TabDestination in some other DB.
The Go in the middle of the begin...end block won't work.
To specify your database for the inserts to TabDesitination you'd be better to use the fully qualified name of the table than calling Use, eg Insert Destiation.dbo.TabDestination...
You need to use If Exists (select... for the second if statement.
Because your Database may not exists when the script compiles, a lot of the sql needs to be exec'd dynamically.
So your script could be re-written as:
if db_id('Destination')is null
begin
Create database Destination
exec ('select * into Destination.dbo.TabDestination from [Source].[dbo].[TabSource]')
end
else
begin
if exists (select name from Destination.sys.objects where name = 'TabDestination' and type = 'u')
insert into Destination.dbo.TabDestination select * from [Source].[dbo].[TabSource]
end
A variation on #Jon Egerton's answer, however there is one case you've neglected to cover: the database exists but the table does not.
DECLARE #sql NVARCHAR(MAX) = N'SELECT *
INTO Destination.dbo.TabDestination
FROM Source.dbo.TabSource;';
IF DB_ID('Destination') IS NULL
BEGIN
PRINT 'Creating database...';
CREATE DATABASE Destination;
PRINT 'Selecting into new table...';
EXEC sp_executeSQL #sql;
END
ELSE
BEGIN
IF EXISTS (SELECT 1 FROM Destination.sys.tables WHERE schema_id = 1
AND name = N'TabDestination')
BEGIN
PRINT 'Inserting into existing table...';
INSERT Destination.dbo.TabDestination SELECT * FROM Source.dbo.TabSource;
END
ELSE
BEGIN
PRINT 'Selecting into new table...';
EXEC sp_executeSQL #sql;
END
END
EDIT
Added PRINT statements for debugging purposes, as I suggested in the follow-up to #Jon's answer.
You just need to get rid of the GO command, its a batch separator so it breaks your begin/end. Oh and you can't use USE like that either.

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