Execute SQL by string dynamic in stored procedure in Sybase - stored-procedures

I've tried this:
AS
DECLARE #sql nvarchar(15000)
BEGIN
IF #X=1
BEGIN
SELECT * FROM X_TABLE_NAME
return
END
ELSE IF #X=2
BEGIN
SET #sql = N'SELECT '+#COLUMNS + ' FROM X_TABLE_NAME '
EXEC (#sql)
END
return
But I get this error:
sybase_query(): Sybase: Server message: SELECT permission denied on object X_TABLE_NAME

Related

Rails migration error: Unicode string return null value inside "execute >> SQL"

I'm trying to do the things below in migration.
Split "Name" as splitted_name array.
SET first_name as splitted_name[0].
SET last_name as splitted_name[-1] if the splitted_name[0] and splitted_name[-1] were differnt.
SET last_name as empty string if the splitted_name[0] and splitted_name[1] are same.
Here is the code.
class ConvertNameIntoFirstAndLastName < ActiveRecord::Migration
def up
execute <<-SQL
DO
$do$
DECLARE
u record;
BEGIN
FOR u IN SELECT * FROM users LOOP
DECLARE
splitted_name text[];
BEGIN
splitted_name := CASE WHEN u.name IS NULL THEN '{''}'
ELSE regexp_split_to_array(u.name, E'\\s+')
END;
UPDATE users
SET
first_name = splitted_name[0],
last_name = CASE WHEN splitted_name[0] = splitted_name[-1] THEN ''
ELSE splitted_name[-1]
END,
name = splitted_name[0] || ' ' || (CASE WHEN splitted_name[0] = splitted_name[-1] THEN '{''}'
ELSE splitted_name[-1]
END)
WHERE id = u.id;
END;
END LOOP;
END;
$do$;
SQL
end
def down
end
end
The problem is u.name always return null when the name is unicode characters. The database encoding is set as Unicode.
Here is the error message.
PG::NotNullViolation: ERROR: null value in column "name" violates not-null constraint
=> The name is actually not null but some Unicode string.
Do you have any idea what is the cause of this error and how to solve this?
Sorry, I was so naive that I didn't know that I should use splitted_name[1] for the first_name and there's no array[-1].
This code worked.
class ConvertNameIntoFirstAndLastName < ActiveRecord::Migration
def up
execute <<-SQL
DO
$do$
DECLARE
u record;
BEGIN
FOR u IN SELECT * FROM users LOOP
DECLARE
splitted_name text[];
BEGIN
splitted_name := regexp_split_to_array(regexp_replace(u.name, ' ', ' '), ' ');
UPDATE users
SET
first_name = splitted_name[1],
last_name = CASE WHEN splitted_name[1] = splitted_name[array_upper(splitted_name, 1)] THEN ''
ELSE splitted_name[array_upper(splitted_name, 1)]
END,
name = splitted_name[1] || ' ' || (CASE WHEN splitted_name[1] = splitted_name[array_upper(splitted_name, 1)] THEN ''
ELSE splitted_name[array_upper(splitted_name, 1)]
END)
WHERE id = u.id;
END;
END LOOP;
END;
$do$;
SQL
end
def down
end
end

How do I pass my variable value into my stored procedure

I created a variable className and I assigned values to it.
I have another procedure in oracle that sends emails to me.
How do I pass this value into header and body of my email?
VARIABLE className varchar2(30)
:classname := 0;
BEGIN
FOR i IN
(
SELECT CLASS_INSTANCE_COUNT , CLASS_NAME
FROM MODEL_CLASS_COUNTS
WHERE TRUNC(COUNT_DATETIME) = TRUNC(SYSDATE)
)
LOOP
IF i.CLASS_INSTANCE_COUNT = 0
THEN
:className := i.CLASS_NAME;
EMAIL('myemail#col.com', 'email header: &className is 0', 'body: count for &className is 0');
END IF;
END LOOP;
END;
/
My guess is that you don't want to have either a SQL*Plus variable or a substitution variable. I'm guessing that you just want
BEGIN
FOR i IN
(
SELECT CLASS_INSTANCE_COUNT , CLASS_NAME
FROM MODEL_CLASS_COUNTS
WHERE TRUNC(COUNT_DATETIME) = TRUNC(SYSDATE)
)
LOOP
IF i.CLASS_INSTANCE_COUNT = 0
THEN
EMAIL('myemail#col.com',
'email header: ' || i.class_name || ' is 0',
'body: count for ' || i.class_name || ' is 0');
END IF;
END LOOP;
END;

'Dynamic' Stored Procedure

I am very new to stored procedures and need some help.
I am trying to create a 'dynamic' stored procedure. When a parameter is NOT NULL then a certain part of the SQL should be added. This is what I have until now.
SELECT
TCId,
ENVId,
UId,
MTId,
TestSetName,
TestCaseName,
InterchangeSeqNo,
InstructionSeqNo,
TransactionSeqNo,
TestCaseDescription
FROM XML_TEST_SET_OVERVIEW
WHERE (ENVId = #MyENVId)
SELECT CASE #MyUId
WHEN IS NOT NULL THEN (AND UId = #MyUId)
END
SELECT CASE #MyMTId
WHEN IS NOT NULL THEN (AND MTId = #MyMTId)
END
SELECT CASE #MyTestSetName
WHEN IS NOT NULL THEN (AND TestSetName = #MyTestSetName)
END
SELECT CASE #MyTestCaseName
WHEN IS NOT NULL THEN (AND TestCaseName = #MyTestCaseName)
END
SELECT CASE #MyInterchangeSeqNo
WHEN IS NOT NULL THEN (AND InterchangeSeqNo = #MyInterchangeSeqNo)
END
SELECT CASE #MyInstructionSeqNo
WHEN IS NOT NULL THEN (AND InstructionSeqNo = #MyInstructionSeqNo)
END
SELECT CASE #MyTransactionSeqNo
WHEN IS NOT NULL THEN (AND TransactionSeqNo = #MyTransactionSeqNo)
END
ORDER BY ENVId, UId, MTId, TestSetName, TestCaseName, InterchangeSeqNo, InstructionSeqNo, TransactionSeqNo
Any help is appreciated
I have to guess at data types here, and I'll let you fill in the extra fluff.
DECLARE #sql NVARCHAR(MAX) = N'SELECT ...
FROM dbo.XML_TEST_SET_OVERVIEW -- always use schema prefix
WHERE ENVId = #MyENVId'
+ CASE WHEN #MyUId IS NOT NULL THEN
N' AND UId = #MyUId' ELSE '' END
+ CASE WHEN #MyMTId IS NOT NULL THEN
N' AND MTId = #MyMTId' ELSE '' END
+ CASE WHEN #MyTestSetName IS NOT NULL THEN
N' AND TestSetName = #MyTestSetName' ELSE '' END
...
+ CASE WHEN #MyTransactionSeqNo IS NOT NULL THEN
N' AND TransactionSeqNo = #MyTransactionSeqNo' ELSE '' END
+ N' ORDER BY ENVId, UId, ...;';
EXEC sp_executesql #sql,
N'#MyENVId INT, #MyUId INT, #MyMTId INT,
#MyTestSetName NVARCHAR(32), ... , #MyTransactionSeqNo INT',
#MyENVId, #MyUId, #MyMTId, #MyTestSetName, ... , #MyTransactioNSeqNo;

How get the error of ActiveRecord::Base.connection.execute?

begin
ActiveRecord::Base.transaction do
// ...
sanitized_sql = "INSERT INTO pinfo ..."
ActiveRecord::Base.connection.execute(sanitized_sql)
end
rescue
// how can I get the error?
end
In the webrick console, the error (1967-07-16?00:00:00) is shown as:
EXECUTE (0.0ms) ODBC::Error: 22008 (241) [unixODBC][FreeTDS][SQL Server]Syntax error converting datetime from character string.: INSERT INTO pinfo (birthdate) VALUES ('1967-07-16?00:00:00')
EXECUTE (0.8ms) IF ##TRANCOUNT > 0 ROLLBACK TRANSACTION
How can I get the above error message (ODBC::Error: 22008 (241) ...) raised from ActiveRecord::Base.connection.execute in rescue?
begin
ActiveRecord::Base.transaction do
// ...
sanitized_sql = "INSERT INTO pinfo ..."
ActiveRecord::Base.connection.execute(sanitized_sql)
end
rescue Exception => exc
logger.error("Message for the log file #{exc.message}")
flash[:notice] = "Store error message #{exec.message}"
end
Thanks

dynamic db2 query in stored procedure

Hi i had a stored procedure as below,
Create PROCEDURE my_car(
in diesel integer,
out milege integer)
P1: BEGIN
SET START_query = 'SELECT*';
SET FROM_CLAUSE = ' FROM car, diesel';
SET WHERE_CLAUSE = ' WHERE car.c1 = diesel.c2';
IF (diesel =0) THEN
SET WHERE_CLAUSE = +WHERE_CLAUSE+'AND car.diesel=0' ;
ELSE
SET WHERE_CLAUSE = +WHERE_CLAUSE+' AND car.diesel='+diesel ;
END IF;
END P1
But its throwing error as below.
DB2 SQL Error: SQLCODE=-402, SQLSTATE=42819, SQLERRMC=+, DRIVER=3.52.90
and if we use || instead of +
ie.,
SET WHERE_CLAUSE = WHERE_CLAUSE || 'AND car.diesel=0' ;
then its throwing error as below,
DB2 SQL Error: SQLCODE=-440, SQLSTATE=42884, SQLERRMC=||;FUNCTION, DRIVER=3.52.90
please help on this.
In DB2, || rather than + is used for string concatenation.
Also, diesel is a character string and you are comparing it to zero. If you want diesel to be a 0 or 1 value, you should set its type to integer. If it needs to be a string, you should compare it to '' or '0' or whatever makes sense.
I'm not sure what you meant by +V_WHERE_CLAUSE+, but your code should look something like this:
IF (diesel = '0') THEN
SET WHERE_CLAUSE = WHERE_CLAUSE || 'AND car.diesel=0';
ELSE
SET WHERE_CLAUSE = WHERE_CLAUSE || ' AND car.diesel=' || diesel;
END IF;
Or maybe just this:
SET WHERE_CLAUSE = WHERE_CLAUSE || ' AND car.diesel=' || diesel;

Resources