Variable is declared but error messages says not - sql

In the stored procedure shown below, I get this error, but I am declaring the #Remarks, so I cannot see what is the issue:
Msg 137, Level 15, State 2, Procedure sp_Insert_EMR_PATIENT_CHECK_TRACKING, Line 53
Must declare the scalar variable "#REMARKS".
Code:
create PROCEDURE [dbo].[sp_Insert_EMR_PATIENT_CHECK_TRACKING]
#HOUR int,
#TIME int,
#MRN nchar(10),
#NURSING_UNIT varchar(12),
#CHECK_DATE datetime,
#MONITOR_CODE nchar(10),
#Remarks nvarchar(500),
#Pain_Level int
AS
BEGIN
SET NOCOUNT ON;
If #Remarks = 'undefined'
BEGIN
SET #Remarks = null
END
IF NOT EXISTS (SELECT *
FROM [OGEN].[EMR_PATIENT_CHECK_TRACKING]
WHERE CHECK_DATE = #CHECK_DATE
AND MRN = #MRN
AND NURSING_UNIT = #NURSING_UNIT
AND HOUR = #HOUR
AND TIME = #TIME
AND MONITOR_CODE = #MONITOR_CODE)
BEGIN
INSERT INTO [OGEN].[EMR_PATIENT_CHECK_TRACKING] ([CHECK_DATE], [MRN], [NURSING_UNIT], [HOUR], [TIME], [MONITOR_CODE], [Pain_Level])
VALUES (#CHECK_DATE, #MRN, #NURSING_UNIT, #HOUR, #TIME, #MONITOR_CODE, #Pain_Level)
IF NOT EXISTS (SELECT *
FROM [OGEN].[EMR_PATIENT_CHECK_TRACKING_REMARK]
WHERE CHECK_DATE = #CHECK_DATE
AND MRN = #MRN
AND NURSING_UNIT = #NURSING_UNIT
AND HOUR = #HOUR
AND MONITOR_CODE = #MONITOR_CODE)
BEGIN
INSERT INTO [OGEN].[EMR_PATIENT_CHECK_TRACKING_REMARK] ([CHECK_DATE], [MRN], [NURSING_UNIT], [HOUR], [MONITOR_CODE], [REMARKS])
VALUES (#CHECK_DATE, #MRN, #NURSING_UNIT, #HOUR, #MONITOR_CODE, ISNULL(#REMARKS,''))
END
ELSE
BEGIN
UPDATE [OGEN].[EMR_PATIENT_CHECK_TRACKING_REMARK]
SET REMARKS = ISNULL(#Remarks,REMARKS)
WHERE CHECK_DATE = #CHECK_DATE
AND [MRN] = #MRN
AND [NURSING_UNIT] = #NURSING_UNIT
AND [HOUR] = #HOUR
AND [MONITOR_CODE] = #MONITOR_CODE
END
END
ELSE
BEGIN
UPDATE [OGEN].[EMR_PATIENT_CHECK_TRACKING]
SET [Pain_Level]=#Pain_Level
WHERE CHECK_DATE = #CHECK_DATE
AND MRN = #MRN
AND NURSING_UNIT = #NURSING_UNIT
AND HOUR = #HOUR
AND TIME = #TIME
AND MONITOR_CODE = #MONITOR_CODE
UPDATE [OGEN].[EMR_PATIENT_CHECK_TRACKING_REMARK]
SET REMARKS = Isnull(#Remarks,REMARKS)
WHERE CHECK_DATE = #CHECK_DATE
AND [MRN] = #MRN
AND [NURSING_UNIT] = #NURSING_UNIT
AND [HOUR] = #HOUR
AND [MONITOR_CODE] = #MONITOR_CODE
END
END

The parameter #Remarks is declared using camel case and later in your stored procedure you reference it as #REMARKS - it could be that you are using a case-sensitive collation and this will result in the error you are seeing.
If your database collation contains "_CI" (e.g. Latin1_General_CI_AS) then it is case-insensitive, if it contains "_CS" it is a case-sensitive collation.

Based on the error information, your server is set to be case-sensitive. This can be confirmed via,
SELECT CONVERT (varchar, SERVERPROPERTY('collation'));
Running the above statement on my case-sensitive server returns, SQL_Latin1_General_CP1_CS_AS.
To bypass that error, you must rename #REMARKS to #Remarks which you had defined or append a COLLATE statement to change the sensitivity to be case-insensitive. On my server, this would be SQL_Latin1_General_CP1_CI_AS.
The better choice would be to remain consistent with your variable naming convention.
On the same case-sensitive server,
DECLARE #value VARCHAR(10) = 'hello'
SELECT #VALUE <<< ERROR.
SELECT #value COLLATE SQL_Latin1_General_CP1_CI_AS <<< returns, 'hello'

Related

Incorrect syntax near the keyword 'And' stored procedure

USE [productDb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_ProcName]
#Name VARCHAR(100),
#PDate NVARCHAR(MAX) NULL,
#City VARCHAR(100),
#Birthday VARCHAR(100)
AS
BEGIN
IF (#Name = '')
IF #Birthday = -1
BEGIN
SET #PDate = And ProductDate >= '08/04/1883'
END
ELSE
BEGIN
SET #PDate = And ProductDate <= '08/04/1883'
END
ELSE
BEGIN
SELECT * FROM Product
END
END
I get these errors:
Msg 156, Level 15, State 1, Procedure usp_ProcName, Line 18
Incorrect syntax near the keyword 'And'.
Msg 156, Level 15, State 1, Procedure usp_ProcName, Line 22
Incorrect syntax near the keyword 'And'.
There are two problems in your stored procedure:
Using SET operator incorrectly. It is an error
As Sean Lange commented out there is an Implicit conversion from datetime to varchar(max). This approach allows you to change formats if it is required, or do date math.
Let's see the first error more precisely:
The SET operator is used to assign data. You write incorrect statements in SET:
set #PDate = And ProductDate >= '08/04/1883'
End
Else
Begin
set #PDate = And ProductDate <= '08/04/1883'
You should set data in SET operator. For example:
Begin
set #PDate = GETDATE()
End
Else
Begin
set #PDate = GETDATE()
end
And the second problem is implicit conversion from datetime to varchar(max). It can be fixed by using correct data type. So this approach allows you to change formats if it is required, or do date math:
ALTER PROCEDURE [dbo].[usp_ProcName]
#Name VARCHAR(100)
, #PDate DateTime = NULL
, #City VARCHAR(100)
, #Birthday VARCHAR(100)
AS
IF (#Name='')
If #Birthday=-1
Begin
set #PDate = GETDATE()
End
Else
Begin
set #PDate = GETDATE()
end

Pass input parameter as column name to update a column value in stored procedure

I have a stored procedure insertvalue with these three parameters:
#stdrollno int,
#sem int,
#IsCheck int,
#subjectname varchar(100),
#test varchar(100)
I have a table demo where there is table named defaulter where there is a column
[Microprocessor th] varchar(50)
[Structured and Object Oriented Analysis and Design th] varchar(50)
whose value I have to update.
So in my stored procedure insertvalue, I wrote this SQL code:
if(#sem = 5)
BEGIN
BEGIN
declare #sql3 nvarchar(500);
set #sql3 = 'update TEdefaulters
set ['+CAST(#test as nvarchar(100))+'] = ['+CAST(#test as nvarchar(100))+'] + '+CAST(#IsCheck as nvarchar(100))+'
where stdrollno = ' +CAST(#stdrollno as nvarchar(100));
exec sp_executesql #sql3
END
BEGIN
update TEdefaulters
set total_theory = total_theory + CONVERT(INT, #ischeck)
where stdrollno = #stdrollno
END
BEGIN
update TEdefaulters
set total_attendance = total_attendance + CONVERT(INT, #ischeck)
where stdrollno = #stdrollno
END
BEGIN
update TEdefaulters
set theory_percentage = (cast((Select total_theory from TEdefaulters where stdrollno=#stdrollno ) as float) / (cast((Select total_theory from TEdefaulters where stdname='total' ) as float))) * 100
where stdrollno=#stdrollno
END
BEGIN
update TEdefaulters
set attendance_percentage = (cast((Select total_attendance from TEdefaulters where stdrollno=#stdrollno ) as float) /(cast((Select total_attendance from TEdefaulters where stdname='total' )as float))) * 100
where stdrollno=#stdrollno
END
END
but it is not working, it causes an error
The values which work is :
exec inserttheoryattendance 5 , 5 , 1 , 'Microprocessor', 'Microprocessor th'
the value which does not work is
exec inserttheoryattendance 5 , 5 , 1 , 'Structured and Object Oriented Analysis and Design', 'Structured and Object Oriented Analysis and Design th'
Cannot convert nvarchar to int
declare #sql nvarchar(50);
50 characters is too short for your SQL String. Try changing it to nvarchar(500)

insert or update the date value as sysdate via stored procedure

I have a procedure:
create proc proc_ins_upd_exp
#id int = 0,
#itemname nvarchar(200),
#price decimal,
#dateofbilling date
as
begin
set nocount on;
if (#id = 0)
insert into exp_tbl (itemname, price, dateofbilling)
values (#itemname, #price, #dateofbilling)
else
update exp_tbl
set itemname = isnull (#itemname, itemname),
price = isnull (#price, price),
dateofbilling = isnull (#dateofbilling , dateofbilling)
where id = #id
set nocount off;
end;
In the table exp_tbl, the column dateofbilling is of datatype date.
How can I insert the value of dateofbilling as getdate via the stored procedure or update the value of dateofbilling with sysdate when this value is NULL?
When I try to execute the stored procedure, I get the error.
execute proc_ins_upd_exp
#itemname = 'test', #price = 100, #dateofbilling = getdate()
You can pass a literal value, or a variable, and nothing else to an execute...
In general (with few exceptions) you cannot have any form of complex expression or function invocation
Declare #currentDate date = getdate()
execute proc_ins_upd_exp #itemname = 'test', #price = 100, #dateofbilling = #currentDate
ALTER Procedure proc_ins_upd_exp
#id int = 0,
#itemname nvarchar(200),
#price decimal,
#dateofbilling date = null
AS
IF #dateofbilling is null
SET #dateofbilling = getdate()

SQL Converting int to varchar

I need help converting an integer to a varchar.
I'm trying to write a procedure that takes in a ProfileID and a Currenttime; using those two values it finds the start time of the profileID and subtracts currenttime from
starttime and returns hours:minutes:seconds.
What am I doing wrong, is there a better way to write this?
Thanks.
CREATE PROCEDURE [dbo].[CalculateElaspedTime]
-- Add the parameters for the stored procedure here
#ProfileID nvarchar(10),
#CurrentDateTime datetime = ''
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
if #CurrentDateTime = CAST('' as datetime)
set #CurrentDateTime = GETDATE()
DECLARE #StartTime datetime;
DECLARE #ElaspedTime time;
DECLARE #hh int;
DECLARE #mm int;
DECLARE #ss int;
Declare #TimeString varchar
set #StartTime = (Select top 1 [DateTime] From Log WHERE ProfileID = #ProfileID);
set #hh = DateDiff(hour,#StartTime,#CurrentDateTime);
set #mm = DateDiff(minute,#StartTime,#CurrentDateTime)-60*#hh;
set #ss = DateDiff(second,#StartTime,#CurrentDateTime)-60*#mm;
set #TimeString = (Select CAST(#hh as varchar)); -- Fails Here
set #ElaspedTime = convert(datetime, cast(#hh as varchar) + ':' + cast(#mm as varchar) + ':' + cast(#ss as varchar));
INSERT INTO Log (ElaspedTime) Values (#ElaspedTime);
END
Try this. All of that excitement in the function may be unnecessary.
CONVERT(varchar(10),(#CurrentDateTime-#Start_Time),108)
One problem you have is this statement:
set #StartTime = (Select top 1 [DateTime] From Log WHERE ProfileID = #ProfileID);
Its results are indeterminate as SQL makes no guarantees about result order unless you explicitly specify it in an ORDER BY clause. You should be using ORDER BY or using an aggregate function like MAX() to get the row you want.
And you're doing a lot more work than necessary. SQL Server (recent versions, anyway) support date arithmetic, with the result of subtracting two dates being another date (offset from the SQL Server epoch of 1 Jan 1900 00:00:00.000. This simpler form ought to do you, unless the elapsed time will exceed 1 day:
create procedure dbo.CalculateElaspedTime
#ProfileID nvarchar(10) ,
#CurrentDateTime datetime = ''
as
set nocount on
declare
#now dateTime ,
#start datetime ,
#elapsed varchar(32)
select #now = case coalesce(#currentDateTime,'') when '' then current_timestamp else #currentDateTime end ,
#start = max( [DateTime] )
from dbo.Log
where ProfileId = #profileId
set #elapsed = convert(varchar,#now-#start,108)
insert dbo.Log ( ElapsedTime ) Values (#elapsed);
return 0
go
If your elapsed time might exceed one day, then your original approach is what you want:
create procedure dbo.CalculateElaspedTime
#ProfileID nvarchar(10) ,
#CurrentDateTime datetime = ''
as
set nocount on
declare #now dateTime = case coalesce(#currentDateTime,'') when '' then current_timestamp else #currentDateTime end ,
declare #start datetime = ( select max([DateTime]) from dbo.Log where profileId = #profileId )
declare #elapsed int = select datediff(ss,#now,#start)
declare
#hh int ,
#mm int ,
#ss int
set #hh = #elapsed / 3600 -- 3600 is seconds/hour
set #elapsed = #elapsed % 3600
set #mm = #elapsed / 60 -- 60 is seconds/minute
set #elapsed = #elapsed % 60
set #ss = #elapsed / 1 -- 1 is seconds/second :)
declare #hhmmss = right('00'+convert(varchar,#hh),2)
+ ':' + right('00'+convert(varchar,#mm),2)
+ ':' + right('00'+convert(varchar,#ss),2)
insert dbo.Log ( ElapsedTime ) Values (#hhmmss);
return 0
go

UPDATE statement not updating table

I am having a problem getting this UPDATE statement to execute. No error is returned, it just does not update the table.
#recordExists varchar(10),
#fileName varchar(50),
#itemCode varchar (50),
--#uploadDate datetime,
#submittedBy varchar(30),
#revision varchar(50),
#itemCode5 varchar(50),
#itemCkDigit varchar(10),
#suffix varchar(10)
AS
DECLARE #sql varchar(1000)
DECLARE #uploadDate datetime
SET #uploadDate = GetDate()
-- Establish update or insert in to the graphics info table.
IF #recordExists = 'Y'
SET #sql = 'UPDATE tblGraphicInfo SET [uploadDate] = ''' + CONVERT(nvarchar(20), #uploadDate) + ''', [submittedBy] = ''' + #submittedBy + ''' WHERE [itemCode] = "' + #itemCode + '"; '
EXEC(#sql)
ELSE
Any help would be appreciated.
FYI, I changed passing the date in because I thought that was the problem. The uploadDate field is defined as a datetime field in the tblGraphicInfo table.
I don't see why you would even need to dynamically string together your UPDATE statement - just use:
DECLARE #sql varchar(1000)
DECLARE #uploadDate datetime
SET #uploadDate = GetDate()
-- Establish update or insert in to the graphics info table.
IF #recordExists = 'Y'
UPDATE dbo.tblGraphicInfo
SET [uploadDate] = CONVERT(NVARCHAR(20), #uploadDate),
[submittedBy] = #submittedBy
WHERE [itemCode] = #itemCode
ELSE
Your issue is your where statement
WHERE [itemCode] = "' + #itemCode + '"; '
You will want to wrap strings in single quote (') not double quote ("). When escaping them in your string, you will need to double the single quotes.
WHERE [itemCode] = ''' + #itemCode + '''; '
You might also look at sp_executsql. It has a much cleaner syntax for handling parameters.
Have you checked to see if any of the variables you are passing in are null? This can cause the whole of your #sql variable to be null too. Try printing your #sql variable with Print() to check it is what it should be.
You could also run profiler to see what is being executed.
If any of your fields are null #sql will be null (Concatinating null yields null).
Is there any reason you are using EXEC rather than doing..
#recordExists varchar(10),
#fileName varchar(50),
#itemCode varchar (50),
--#uploadDate datetime,
#submittedBy varchar(30),
#revision varchar(50),
#itemCode5 varchar(50),
#itemCkDigit varchar(10),
#suffix varchar(10)
AS
DECLARE #sql varchar(1000)
DECLARE #uploadDate datetime
SET #uploadDate = GetDate()
-- Establish update or insert in to the graphics info table.
IF #recordExists = 'Y'
UPDATE tblGraphicInfo SET [uploadDate] = #uploadDate, [submittedBy] = #submittedBy WHERE [itemCode] = #itemCode
ELSE
Additionally if you perform more than one line inside an if else you will need to wrap it in a BEGIN END
You could actually do the following instead, the ##ROWCOUNT=0 will test if the previous statement modified no records and so needs to be an insert
UPDATE tblGraphicInfo SET [uploadDate] = #uploadDate, [submittedBy] = #submittedBy WHERE [itemCode] = #itemCode
if ##ROWCOUNT=0 then
INSERT into tblGraphicInfo (uploadDate,submittedBy,itemCode) values (#uploadDate,#submittedBy,#itemCode)