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
...
Related
I am using Zend Framework 2 to generate the following escaped single-quote SQL query,
SELECT
`document`.*
FROM
`document`
WHERE
(
`document`.`document_taxon` LIKE '%Men\'s Health %' --escaped quote
AND `document`.`document_source_id` = ' 5 '
AND `document`.`document_published` = ' 1 '
AND `document`.`document_deleted` = ' 0 '
)
ORDER BY
`document_id` DESC
LIMIT 25 OFFSET 0
But I am getting this instead,
SELECT
`document`.*
FROM
`document`
WHERE
(
`document`.`document_taxon` LIKE '%Men's Health%'
AND `document`.`document_source_id` = ' 5 '
AND `document`.`document_published` = ' 1 '
AND `document`.`document_deleted` = ' 0 '
)
ORDER BY
`document_id` DESC
LIMIT 25 OFFSET 0
And here is my code
class DocumentTable extends TableGateway
{
....
$select=$this->getSql()->select();
$select->columns(array('*'));
$select->where
->NEST
->like('document_taxon', '%' . $label . '%')
->and
->equalTo('document_source_id', $sourceId)
->and
->equalTo('document_published', true)
->and
->equalTo('document_deleted', 0)
->UNNEST;
$select->order('document_id DESC');
$select->limit($limit);
$select->offset($offset);
...
}
I tried,
$this->getAdapter()->getPlatform()->quoteValue($string)
\Zend\Db\Sql\Expression("%". $label . "%")
str_replace("'", "\'", $label)
But I didn’t have much luck. I welcome any suggestion to solve this issue.
I worked it out. I was passing a normalized “label” value instead of the raw value. The above code snippet works fine.
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(?).
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;
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
--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 + ')'