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)
Related
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])
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.
I'm writing the following code into SQL Server Management Studio
DECLARE #tab AS table(ProductID integer, StockCount integer)
INSERT INTO #tab
SELECT ProductID, InStock + OnOrder
FROM Inventory.Product;
GO
SELECT * FROM #tab;
When I execute the code, an error occurs. Which of the two following actions could I take to prevent the error from happening?
1
Modify the INSERT statement to:
INSERT INTO #tab
SELECT ProductID, InStock
FROM Inventory.Product;
2
--Remove the GO command
3
--Use a temporary table named #tab instead of the #tab variable
4
--Add a second GO command after the final SELECT statement
Personally, I think 1 and 2 are correct, but with slight disability issues I'm not confident enough in my answer being 100% correct, if anyone could give any pointers that would certainly help or explain why I may be wrong.
EDIT: THE ERROR I'M GIVEN WHEN I RUN A QUERY IS:
Msg 208, Level 16, State 1, Line 2
Invalid object name 'Inventory.Product'.
Msg 1087, Level 15, State 2, Line 6
Must declare the table variable "#tab".
The reason you are getting the error is because a Variable's scope is the transaction in which it is declared.
When you declare a variable as soon as you put the GO key word which is a batch separator the variable is not visible after that GO keyword.
Anyway these are not the factors which should decide whether to use a Table Variable or a Temp table.
Have a look at this question What's the difference between a temp table and table variable in SQL Server to learn about the differences between the Temp tables and table variables and then decide what is best for you.
I would say 2 & 3 are correct. The Go will not allow the variable to carry over to the second query, but you could get around this by using a temporary table instead of a variable.
2 & 3 are correct indeed.
Remove the go makes it as a single batch, so #tab var would be
accessible for second SELECT stmnt
If you need though to split it into two batches, then as advised before - make it a table.
This question has been asked before but it all involved using "go" which I am not in need of here, at least I believe so.
I am following this tut https://www.youtube.com/watch?v=-xMGwiV5A6o, near the 1:25 mark exactly. And his seems to execute while mine doesn't.
Select * From Snacks
Create Proc spGetSnackByID
#Id int
as
Begin
Select Id, Name, Location
from Snacks where Id = #Id
End
Here is the exact error, being highlighted with the "BEGIN" statement:
"Msg 111, Level 15, State 1, Procedure spGetSnackByID, Line 7
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch."
If you want to keep the script as it is (select followed by a create procedure), you can construct the creation of the stored procedure in a NVARCHAR and EXECUTE it using sp_executesql. This way the CREATE statement is the first statement. Like this:
Select * From Snacks
EXECUTE sp_executesql N'
Create Proc spGetSnackByID
#Id int
as
Begin
Select Id, Name, Location
from Snacks where Id = #Id
End
';
Yes, SQL Server wants the create procedure as the first line. Just remark out the select above, it is not what you want anyway, because you have specified the fields in the stored procedure.
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.