Updating Reminder table with the date passed(ManualEntry) - stored-procedures

--Parameters---
#InstrumentID VARCHAR(MAX),
#ReminderSentDate datetime,
#Return INT OUTPUT
--========================================================================================= ===
AS
BEGIN
BEGIN TRANSACTION
--===============================UPDATE LAST REMINDER SENT=======================================
DECLARE #Reminder VARCHAR(MAX)
SET #Reminder = 'UPDATE InstrumentReminderSent SET ReminderSentDate=#ReminderSentDate WHERE InstrumentID in (' + #InstrumentID + ')'
EXEC(#Reminder)
SET #Return=##ROWCOUNT
COMMIT TRANSACTION
This is SP If I execute this giving values of InstrumentID=7 and ReminderSentDate ='2014-02-28' I'm getting Error as "Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#ReminderSentDate"."

It looks like a scope issue. Have you tried making the #ReminderSentDate dynamic in the update statement?
SET #Reminder = 'UPDATE InstrumentReminderSent SET ReminderSentDate=' + #ReminderSentDate + ' WHERE InstrumentID in (' + #InstrumentID + ')'

Related

How to pass multiple OR and AND condition in Activate Record in Rails as a string

I'm new in Ruby on rails and I would like to fetch records based on a condition, and I'm passing the condition in a string format. Moreover, I will pass the query in multiple OR and AND conditions. However, right now, I'm stuck that how to pass the query in string format in rails
I have attached the screenshot
#data= CustomAttribute.includes(:custom_attribute_values).where(id: 18, company_id: current_user.company_id).first
The above line executed successfully and gave the output
<CustomAttribute id: 18, data_type: "string", label: "Marital status", code: "marital_status", entity_type: "member", company_id: 1, created_at: "2021-03-10 10:16:15", updated_at: "2021-03-10 10:16:27", is_active: true, is_default: false, rank: nil, is_identifier: false>
but when I executed the below line it gave me the error that
#data.custom_attribute_values.where("\""+"value_string"+"\""+"="+"\""+'Single'+"\"").size
ERROR: column "Single" does not exist
the Single is the value which I would like to count
Here is my code for the dynamic query creation
logical_operator = 'OR'
#custom_attribute = CustomAttribute.includes(:custom_attribute_values).where(id: custom_attribute_ids, company_id: current_user.company_id)
query=""
#custom_attribute.each_with_index do |attribute_object, index|
filter_object= filter_params[:filters].find {|x| x['custom_attribute_id']==attribute_object['id']}
if filter_object.present?
query += "("+ '"' +'value_'+attribute_object.data_type + '"' + ' ' + filter_object['operator'] + ' ' + "'" + filter_object['value'].to_s + "'"+ ")"
end
if index != #custom_attribute.length-1
query+=' '+logical_operator+' '
end
if index == #custom_attribute.length-1
query="'" + " ( " + query + " ) " + "'"
end
end
byebug
puts(#custom_attribute.first.custom_attribute_values.where(query).size)
Any time you're doing a lot of escaping and string addition in Ruby you're doing it wrong. If we clean up how you build your SQL:
"\""+"value_string"+"\""+"="+"\""+'Single'+"\""
things will be clearer. First, put space around your operators for readability:
"\"" + "value_string" + "\"" + "=" + "\"" + 'Single' + "\""
Next, don't use double quotes unless you need them for escape codes (such as \n) or interpolation:
'"' + 'value_string' + '"' + '=' + '"' + 'Single' + '"'
Now we see that we're adding several constant strings so there's no need to add them at all, a single string literal will do:
'"value_string" = "Single"'
Standard SQL uses double quotes for identifiers (such as table and column names) and single quotes for strings. So your query is asking for all rows where the value_string column equals the Single column and there's your error.
You want to use single quotes for the string (and %q(...) to quote the whole thing to avoid adding escapes back in):
#data.custom_attribute_values.where(
%q("value_string" = 'Single')
)
Or better, let ActiveRecord build the query:
# With a positional placeholder:
#data.custom_attribute_values.where('value_string = ?', 'Single')
# Or a named placeholder:
#data.custom_attribute_values.where('value_string = :s', s: 'Single')
# Or most idiomatic:
#data.custom_attribute_values.where(value_string: 'Single')

Dynamic Sql Error , Invalid syntax near '>'

I have the below dynamic sql statement and I'm getting the "Incorrect syntax near '>'. error message. I can not figure out what the problem is, not sure if I'm missing a tick mark or not. I've tried to add extra tick marks and nothing seems to work.
Declare #filters varchar(max)
SET #filters = 'Where PaymentAmount > 0'
BEGIN
SET #filters = #filters + ' AND CONVERT(DATE, AccountingDate) >= '''+ cast #BeginDate as nvarchar) + ''''
SET #filters = #filters + ' AND CONVERT(DATE, AccountingDate) <= '''+ cast(#EndDate as nvarchar) + ''''
END
SET #SQLString = 'Select
,[ReturnDate]
,[PolicyNumber]
From dbo.Bil_ReturnsRepository' + #filters
EXEC(#SQLString)
You need another space before you concat #filters to #SQLString.
SET #SQLString = 'Select
,[ReturnDate]
,[PolicyNumber]
From dbo.Bil_ReturnsRepository ' + #filters
Otherwise the generated sql would be
...
From dbo.Bil_ReturnsRepositoryWhere PaymentAmount > 0
...

Passing in variables to SQL Server stored procedure, where clause

I am writing an application responsible for archiving data and we have the configuration in a database table
Id | TableName | ColumnName | RetentionAmountInDays
1 | DeviceData | MetricTime | 3
So when faced with this configuration, I should archive all data in the DeviceData table where the MetricTime value is before 3 days ago.
The reason I am doing this dynamically is the table names and column names differ (there would be multiple rows)
For each configuration this stored procedure is called
CREATE PROCEDURE GetDynamicDataForArchive
#TableName nvarchar(100),
#ColumnName nvarchar(100),
#OlderThanDate datetime2(7)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql nvarchar(1000);
SET #sql = 'SELECT * FROM ' + #TableName + ' WHERE ' + #ColumnName + ' < #OlderThanDate';
exec sp_executesql #sql;
END
And an example exec line
exec dbo.GetDynamicDataForArchive 'DeviceData', 'MetricTime', '2017-04-16 20:29:29.647'
This results in:
Conversion failed when converting date and/or time from character string.
So something is up with how I am passing in the datetime2 or how I am forming the where clause.
Replace this statement:
SET #sql = 'SELECT * FROM ' + #TableName + ' WHERE ' + #ColumnName + ' < #OlderThanDate'
by
SET #sql = 'SELECT * FROM ' + #TableName + ' WHERE [' + #ColumnName + '] < ''' + cast(#OlderThanDate as varchar(23)) + '''';
I don't particularly like having to convert the datetime to a varchar value though, perhaps there is a better way to do this(?).

IBM DB2 Equivalent syntax for SQL Server Stored Procedure - error while deploying

I am newbie to IBM db2.Need to convert the below mentioned SP to db2 syntax. But i am stuck with many equivalents used or available in Db2. Even google research doesn't show how exactly we can compare object id of tables in db2 as I am doing in SQL Server stored procedure. Could anyone suggest me with right way to proceed?
EDIT: I have updated with equivalent DB2 syntax, but facing below error while deploying at the particular line, Can anyone identify and help me understand what is wrong with this syntax or the problem lies anywhere else in the procedure.
line no 25 : DECLARE v_sqlstate CHAR(5);
BACKUPTABLE: 25: An unexpected token "<variable declaration> was found following "". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.18.60
An unexpected token variable declaration was found following "". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.18.60
SQL Server Stored procedure syntax:
CREATE PROCEDURE [dbo].[BackUpTable]
#TableName sysname
AS
BEGIN
SET nocount ON
DECLARE #sql VARCHAR(500)
IF EXISTS (SELECT *
FROM sys.objects
WHERE object_id = Object_id(N'[dbo].[' + #TableName+'_EST' + ']')
AND TYPE IN ( N'U' ))
BEGIN
SET #sql = 'declare #Done bit
set #Done = 0
while #Done = 0
begin
delete top (100000)
from ' + #TableName + '_Bak' +
' if ##rowcount = 0
set #Done = 1
end;'
SET #sql = #sql + 'insert into ' + #TableName + '_Bak select * from ' +
#TableName +'_EST'
EXEC(#sql)
END
ELSE
BEGIN
DECLARE #err_message VARCHAR(300)
SELECT #err_message = 'The table "' + Isnull(#TableName, 'null') +
'" does not exist'
RAISERROR (#err_message, 16, 1)
END
END
DB2 SYNTAX CREATED SO FAR:
CREATE OR REPLACE PROCEDURE BackUpTable (IN TableName VARCHAR(128))
DYNAMIC RESULT SETS 1
BEGIN
DECLARE dynamicSql VARCHAR(500);
IF(EXISTS(
SELECT * FROM SYSIBM.SYSTABLES
WHERE NAME = TableName||'_EST'
)
)
THEN
SET dynamicSql = 'DELETE FROM '||TableName ||'_BAK';
SET dynamicSql = dynamicSql ||'insert into ' || TableName || '_BAK select * from ' ||
TableName || '_EST';
EXECUTE IMMEDIATE dynamicSql;
ELSE
DECLARE v_sqlstate CHAR(5);
DECLARE v_sqlcode INT;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE SQLCODE INT DEFAULT 0;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SELECT SQLSTATE, SQLCODE
INTO v_sqlstate, v_sqlcode
FROM sysibm.sysdummy1;
SET O_Error_Msg = 'TABLE IS NOT AVAILABLE:: SQLState : '||v_sqlstate||' SQLCode : '||v_sqlcode ;
END;
END IF;
END
on z/os you can do it:
IF( EXISTS( SELECT 1 FROM QSYS2.SYSTABLES WHERE TABLE_SCHEMA = 'YOURLIB' AND TABLE_NAME = 'YOURTABLENAME')) THEN
DROP TABLE YOURLIB.YOURTABLENAME;
END IF;

How to get user name who updated the data from UI in MVC 5 and Entity Framework

We have a website in ASP.NET MVC 5 with Entity Framework.
When a logged in user made changes in UI (i.e. update the data) we save/update/delete the data in SQL Server as per operation performed by the user.
We also have a trigger for audit trailing.
With the trigger, table format for storing data is as below:
[AuditID]
[Type] -- Contains operation performed (Insert (I), Update (U), Delete (D))
[TableName]
[PK] -- Primary Key
[FieldName]
[OldValue]
[NewValue]
[UpdateDate]
[UserName]
We are storing SYSTEM_USER in [UserName] column.
If we have any solution to store the [UserName] who actually made changes from UI instead of system_user?
Do we have any approach to pass [UserName] from application (UI) to the trigger?
Please share your thoughts.
I have one solution - to add UpdatedBy column name in all the tables so that trigger can easily get the value of UpdatedBy column from magic tables or from main tables.
Please suggest best approach.
Below is the trigger used.
CREATE TRIGGER [ids].[tr_AuditEmploee]
ON Employee
FOR INSERT, UPDATE, DELETE
AS
DECLARE #bit INT,
#field INT,
#maxfield INT,
#char INT,
#fieldname VARCHAR(128),
#TableName VARCHAR(128),
#PKCols VARCHAR(1000),
#sql VARCHAR(2000),
#UpdateDate VARCHAR(21),
#UserName VARCHAR(128),
#Type CHAR(1),
#PKSelect VARCHAR(1000)
--You will need to change #TableName to match the table to be audited
SELECT #TableName = 'Employee'
-- date and user
SELECT
#UserName = SYSTEM_USER,
#UpdateDate = CONVERT(VARCHAR(8), GETDATE(), 112) + ' ' + CONVERT(VARCHAR(12), GETDATE(), 114)
-- Action
IF EXISTS (SELECT * FROM inserted)
IF EXISTS (SELECT * FROM deleted)
SELECT #Type = 'U'
ELSE
SELECT #Type = 'I'
ELSE
SELECT #Type = 'D'
-- get list of columns
SELECT * INTO #ins FROM inserted
SELECT * INTO #del FROM deleted
-- Get primary key columns for full outer join
SELECT
#PKCols = COALESCE(#PKCols + ' and', ' on')
+ ' i.' + c.COLUMN_NAME + ' = d.' + c.COLUMN_NAME
FROM
INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE
pk.TABLE_NAME = #TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
-- Get primary key select for insert
SELECT
#PKSelect = COALESCE(#PKSelect+'+','')
+ '''' + COLUMN_NAME
+ '=''+convert(varchar(100),
coalesce(i.' + COLUMN_NAME +', d.' + COLUMN_NAME + '))+'''''
FROM
INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE
pk.TABLE_NAME = #TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
IF #PKCols IS NULL
BEGIN
RAISERROR('no PK on table %s', 16, -1, #TableName)
RETURN
END
SELECT
#field = 0,
#maxfield = MAX(ORDINAL_POSITION)
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = #TableName
WHILE #field < #maxfield
BEGIN
SELECT #field = MIN(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableName
AND ORDINAL_POSITION > #field
SELECT #bit = (#field - 1 )% 8 + 1
SELECT #bit = POWER(2,#bit - 1)
SELECT #char = ((#field - 1) / 8) + 1
IF SUBSTRING(COLUMNS_UPDATED(),#char, 1) & #bit > 0 OR #Type IN ('I','D')
BEGIN
SELECT #fieldname = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableName
AND ORDINAL_POSITION = #field
SELECT #sql = '
insert [audit].[AuditEmployee] ( Type,
TableName,
PK,
FieldName,
OldValue,
NewValue,
UpdateDate,
UserName)
select ''' + #Type + ''','''
+ #TableName + ''',' + #PKSelect
+ ',''' + #fieldname + ''''
+ ',convert(varchar(1000),d.' + #fieldname + ')'
+ ',convert(varchar(1000),i.' + #fieldname + ')'
+ ',''' + #UpdateDate + ''''
+ ',''' + #UserName + ''''
+ ' from #ins i full outer join #del d'
+ #PKCols
+ ' where i.' + #fieldname + ' <> d.' + #fieldname
+ ' or (i.' + #fieldname + ' is null and d.' + #fieldname + ' is not null)'
+ ' or (i.' + #fieldname + ' is not null and d.' + #fieldname + ' is null)'
EXEC (#sql)
END
END

Resources