transact sql - can't select from variable - sql

I'm trying to take the ID of a new record inserted into TABLE A and use it in a subsequent insert.
But I'm getting an error saying that the newUserId variable isn't declared.
it's actually a table variable.
The code looks like this;
USE Acme;
GO
DECLARE #userPrincipalName VARCHAR(100),
#displayName VARCHAR(100),
#domainName VARCHAR(100),
#tId INT,
#uname VARCHAR(100);
DECLARE #newUserid TABLE (
id INT
);
-- FILL ME IN
SET #domainName = 'mydomain.org';
SET #userPrincipalName = 'ppan#mydomain.org';
SET #displayName = 'Pan, Peter';
SET #tId=4;
SET #uname = 'ppan';
INSERT INTO dbo.User
(column list)
OUTPUT Inserted.ID INTO #newUserId
SELECT '', #domainName, getutcdate(), #userPrincipalName, #displayName, other fields
-- Create New Profile Using NewID ** THIS IS WHERE IT DIES
INSERT INTO dbo.UserProfile
SELECT #newUserId.id,
'{}', GETDATE(), getdate(), ''
The specific error is:
8:55:51 AMStarted executing query at Line 1
Commands completed successfully.
8:55:51 AMStarted executing query at Line 3
Msg 137, Level 16, State 1, Line 36
Must declare the scalar variable "#newUserid".
Total execution time: 00:00:00.017
I've abbreviated the code for the sake of this post but line 36 is where I'm referencing SELECT #newUserId.id
Any tips would be appreciated.
Thanks

Because #newUserId is a table variable you can't select it as a variable.
you can try to use INSERT INTO ....SELECT ... FROM
INSERT INTO dbo.UserProfile
SELECT id, '{}', GETDATE(), GETDATE(), ''
FROM #newUserId

Related

Passing Variable from stored procedure to another

I have a stored procedure that I need pass the parameter from one to the other procedure and have it display as an output. I am declaring the following in the header of my procedure [xxx].[zzzz_ERP_Cyyyyy]
DECLARE #ProcedureLogRowKey INT
DECLARE #ProcedureRecordCount INT
DECLARE #ProcedureStartDateTime DATETIME
DECLARE #ProcedureLog_Note NVARCHAR(100)
EXEC [XXX].[spciProcedurePerformanceStartRecord_help]
'.[xxx].[zzzz_ERP_Cyyyyy]',
1,
#ProcedureStartDateTime,
'Contract Check',
#ProcedureLogRowKey OUTPUT
I am getting the following error:
Msg 515, Level 16, State 2, Procedure spciProcedurePerformanceStartRecord_help, Line 33 [Batch Start Line 17]
Cannot insert the value NULL into column 'YSTRTDTT_0', table '000.xxx.YPERLOG'; column does not allow nulls. INSERT fails.
Here is the procedure that I am getting the variable from to pass into my procedure [xxx].[zzzz_ERP_Cyyyyy]
CREATE PROCEDURE [xxx].[spciProcedurePerformanceStartRecord_help]
(#ProcedureName VARCHAR(200),
#ProcedureRecordCount INT = 1,
#ProcedureStartDateTime DATETIME = GETDATE,
#ProcedureLog_Note NVARCHAR(100),
#ProcedureLogRowKey INT OUTPUT --- I am passing this into my proc and
displaying it as output
)
AS
BEGIN
-- Set Default return for #ProcedureLogRowKey, used if logging is not turned on.
SET #ProcedureLogRowKey = -1;
-- Check to see if performance logging is enabled
IF EXISTS(SELECT ROWID FROM LIVE.YPERCON
WHERE YPROCNM_0 = #ProcedureName AND YLOGENA_0 = 2)
BEGIN
INSERT INTO xxx.YPERLOG (YROWKEY_0, YPROCNM_0, YRECCNT_0, YSTRTDTT_0, YENDDTT_0, YLOGNOTE_0,
YDURMS_0, CREDATTIM_0, UPDDATTIM_0, AUUID_0, CREUSR_0, UPDUSR_0)
SELECT
ISNULL(MAX(YROWKEY_0), 0) + 1,
#ProcedureName, #ProcedureRecordCount, #ProcedureStartDateTime,
'1753-01-01',
#ProcedureLog_Note, 0,
GETDATE(), GETDATE(), NEWID(), 'admin', 'admin'
FROM
xxx.YPERLOG
SELECT #ProcedureLogRowKey = ISNULL(MAX(YROWKEY_0), 0)
FROM xxx.YPERLOG
END
ELSE
BEGIN
DECLARE #Count integer
SELECT #Count = COUNT(0)
FROM LIVE.YPERERR
WHERE YPROCNM_0 = #ProcedureName
IS ISNULL(#Count, 0) = 0
INSERT INTO LIVE.YPERERR (YPROCNM_0, YREQDT_0, YLASTDT_0, YERRMSG_0,
CREDATTIM_0, UPDDATTIM_0, AUUID_0, CREUSR_0, UPDUSR_0)
VALUES (#ProcedureName, GETDATE(), '1753-01-01', 'Controller not defined or active',
GETDATE(), GETDATE(), NEWID(), 'admin', 'admin')
ELSE
UPDATE xxx.YPERERR
SET YLASTDT_0 = GETDATE()
WHERE YPROCNM_0 = #ProcedureName
END
END
Thanks in advance.
The issue is in procedure [xxx].[spciProcedurePerformanceStartRecord_help] with parameter #ProcedureStartDateTime DATETIME. You should set its default value this way:
In declaration set default value as NULL
#ProcedureStartDateTime DATETIME = NULL
It would look like tihs
CREATE PROCEDURE [xxx].[spciProcedurePerformanceStartRecord_help]
(
#ProcedureName VARCHAR(200)
,#ProcedureRecordCount INT = 1
,#ProcedureStartDateTime DATETIME = NULL
,#ProcedureLog_Note NVARCHAR(100)
,#ProcedureLogRowKey INT OUTPUT
)
AS
BEGIN
-- procedure's body
END
Inside procedure, at the beginning, check if #ProcedureStartDateTime parameter's value is NULL and if it is, set its value to GETDATE().
SET #ProcedureStartDateTime = ISNULL(#ProcedureStartDateTime, GETDATE())
You have declared DECLARE #ProcedureStartDateTime DATETIME and did not set any value to it. so, it is having NULL value and you are passing NULL value to the procedure execution
EXEC [XXX].[spciProcedurePerformanceStartRecord_help]
'.[xxx].[zzzz_ERP_Cyyyyy]',
1,
#ProcedureStartDateTime, -- NULL value passed here
'Contract Check',
#ProcedureLogRowKey OUTPUT
As the target column 'YSTRTDTT_0', table '000.xxx.YPERLOG', does not allow NULLs, you are getting error.

Code a SQL Server stored procedure to update vc_statusID

I coded a stored procedure called vc_FinishVidCast that accepts an int as an input parameter that will be a vc_VidCastID that we will need to mark as finished. The act of finishing a VidCast means we must change its EndDateTime to be the current Date and Time (think GetDate()) and change the vc_StatusID to the vc_StatusID for the ‘Finished’ status.
alter procedure vc_FinishVidCast
(#vidCastID int, #finished int)
as
begin
update vc_VidCast
set vc_StatusID = #finished
where vc_VidCastID = #vidCastID
end
go
exec vc_FinishVidCast '859', '2'
DECLARE #newVC INT
INSERT INTO vc_VidCast (VidCastTitle, StartDateTime, ScheduleDurationMinutes, vc_UserID,vc_StatusID)
VALUES ('Finally done with sprocs', DATEADD(n, -45, GETDATE()), 45,
(SELECT vc_UserID FROM vc_User WHERE UserName = 'tardy'),
(SELECT vc_StatusID FROM vc_Status WHERE StatusText='Started')
)
SET #newVC = ##identity
SELECT *
FROM vc_VidCast
WHERE vc_VidCastID = #newVC
EXEC vc_FinishVidCast #newVC
SELECT * FROM vc_VidCast WHERE vc_VidCastID = #newVC
I get an error:
Msg 201, Level 16, State 4, Procedure vc_FinishVidCast, Line 179
Procedure or function 'vc_FinishVidCast' expects parameter '#finished', which was not supplied.
You may want to try something like below:
DECLARE #Finished_ID INT
SELECT #Finished_ID = vc_StatusID FROM vc_Status WHERE StatusText='FInished'
EXEC vc_FinishVidCast #newVC,#Finished_ID

How to pass multiple values for a column in sql Stored Procedure?

i have two tables, such as
Queue
QueueID
LogParameters
QueueParameters
QueueParametersID
QueueID
LogParametersKey
LogParametersValue
I have to write SP inorder to make an entry in both the tables,
LogParameterKey and LogParameterValue may contains multiple values but the QueueID for each values should be same and QueueParameterID could be different.
**QueueID** **LogParameters**
1 AA
**QueueParametersID** **QueueID** **LogParametersKey** **LogParametersValue**
1 1 FirstName Mohammad
2 1 LastName Salman
3 1 Age 17
How do i pass multiple values for LogParameterKey and LogParameterValue?.. Someone suggested me to use Array for this... Is there's any other way?
CREATE Procedure AddQueue
#LogParameters NVARCHAR(255)
#AuditParameters AS AuditParameter READONLY,-- UserDefinedTable
AS
SET NOCOUNT ON;
BEGIN
DECLARE #QueueID BIGINT
EXECUTE dbo.procInsertQueue
#LogParameters = #LogParameters,
#QueueID = #QueueID OUTPUT
DECLARE #GetQueueID BIGINT = (SELECT QueuesID FROM Queues WHERE LogParameters= #LogParameters
DECLARE #AuditQueueParametersID BIGINT
DECLARE #TempTable TABLE(
ParameterKey NVARCHAR(255),
ParameterValue NVARCHAR(255),
AuditQueuesID BIGINT)
INSERT INTO #TempTable(ParameterKey,ParameterValue,QueuesID)
SELECT ParameterKey,ParameterValue,#GetQueueID FROM #AuditParameters
DECLARE #LogParameterKey NVARCHAR(255) = (SELECT ParameterKey FROM #TempTable WHERE QueuesID = #GetQueueID)
DECLARE #LogParameterValue NVARCHAR(255) = (SELECT ParameterValue FROM #TempTable WHERE QueuesID = #GetQueueID)
EXECUTE dbo.procAddQueueParameters
#AuditQueueID = #GetQueueID
#LogParametersKey = #LogParametersKey,
#LogParametersValue = #LogParametersValue,
#QueueParametersID = #QueueParametersID OUTPUT
END
END
1. Use User-Defined Table Types
https://technet.microsoft.com/en-us/library/bb522526(v=sql.105).aspx
2. Generate xml string and parse in SP
3.Use temp table
CREATE TABLE #Input
(
QueueParametersID ..
QueueID ..
LogParametersKey ..
LogParametersValue ..
)
--INSERT VALUES
EXEC dbo.YouSP
IN SP use table #Input

SQL Server: CREATE FUNCTION with declare variables inside

I would like to create a function in SQL Server.
In this function, I need to define some variables and then use it in the SELECT.
SQL looks like below:
CREATE FUNCTION [dbo].[MyFussnction]
(
#path [nvarchar](10)
)
RETURNS TABLE
BEGIN
DECLARE #xx varchar(50);
SET #xx = 'Windows%';
RETURN
SELECT * FROM MyTable WHERE DataPath LIKE #path AND XX LIKE #xx;
END
But, it is not able to be created and the error says:
Msg 102, Level 15, State 31, Procedure MyFussnction, Line 12 [Batch Start Line 0]
Incorrect syntax near 'BEGIN'.
You need to define columns of table to return, then you can use declare, something like below
CREATE FUNCTION [dbo].[MyFussnction] (
#path [nvarchar](10)
)
RETURNS #Mytable TABLE
(
ID int PRIMARY KEY NOT NULL
-- define other columns
)
AS
BEGIN
DECLARE #xx varchar(50);
SET #xx = 'Windows%';
Insert into #Mytable
SELECT Id FROM MyTable WHERE DataPath LIKE #path AND XX LIKE #xx;
RETURN;
END

Trigger on delete or update that captures the sender and the command

I need to find out who is deleting / updating the data on table THETABLE, the time, using what program, and the command that is sent to the database that caused the modification.
From googling and asking some colleagues, the recommended way is on delete trigger. I know how to create trigger, for example:
create trigger whodunit
on THETABLE
for delete
as begin
insert into MyAuditTbl(moddate, ...
end
But how do I get the command that is sent to the DB (query / stored procedure), application name, IP address, etc.?
I found some script and customized it to fit my needs:
create trigger AuditTHETABLE
on THETABLE
for delete, update
as begin
set nocount on
declare #shouldlog bit, #insertcount bigint, #deletecount bigint
select
#shouldlog = 1,
#insertcount = (select count(*) from inserted),
#deletecount = (select count(*) from deleted)
-- if no rows are changed, do not log
if #insertcount < 1 and #deletecount < 1 begin
select #shouldlog = 0
end
-- ... other checks whether to log or not
if #shouldlog = 1 begin
-- prepare variable to capture last command
declare #buffer table (
eventtype nvarchar(30),
parameters int,
eventinfo nvarchar(4000)
)
-- use DBCC INPUTBUFFER to capture last command
-- unfortunately only the first 255 characters are captured
insert #buffer
exec sp_executesql N'DBCC INPUTBUFFER(##spid) WITH NO_INFOMSGS'
declare #lastcommand varchar(max)
select #lastcommand = eventinfo from #buffer
-- insert into audit table
insert into myauditlog(
eventdate, tablename, hostname,
appname, insertcount, deletecount, command
) values(
getdate(),
'THETABLE',
host_name(),
app_name(),
#insertcount,
#deletecount,
#lastcommand
)
end
end