Unable to execute dynamic sql Error:global_names parameter must be set to TRUE for this operation - plsql

I have a remote table with blob column accessed via a db link. I want to insert a blob from my local table to remote table blob column.I am executing dynamic sql like follows
declare
theblob blob;
theclob clob;
thenumber number;
begin
select base64encode2(image) into theclob from per_images where image_id = 113077;
execute immediate 'insert into image#APPSERP2ERPAPPS(column1,column2,column3) values((select null from dual),(select base64encode2(image) from per_images where image_id = 113077),(select ceil(5.4) from dual))';
commit;
end;
When i run the sql i get ORA-02069: global_names parameter must be set to TRUE for this operation.
If i do ALTER SESSION SET GLOBAL_NAMES = true then i get database link APPSERP2ERPAPPS.CSN.EDU.PK connects to TEST.CSN.EDU.PK error while inserting into blob.
Kindly tell me how can i insert blob into remote table blob column.
Thanks

To be able to insert over a dblink the insert sentence must match this format
Insert into table2#dblink select * from Table1
here more info.

Related

Stored Procedure returns "Error Code: 1054. Unknown column 'schema.table.col' in 'field list'" when Creating different temporary table on same session

When using a stored procedure to dynamically generate a table based on configuration and return a result set (SELECT) with the records in that table, the second call to that procedure to generate a different table structure returns no records and it reports a missing column from a previous temporary table of the same name.
I tried this with MariaDB 10.3 and 10.1.21 and received the same result. I have minimized my code here to the minimum to demonstrate the error after trying several variations of single and multiple sub-procedures.
I also tried using some transaction control with COMMITS after executing the process, before trying to start the process with a different parameter, but got the same results.
DROP PROCEDURE IF EXISTS CreateATable;
DELIMITER $$
CREATE PROCEDURE CreateATable( _TableType tinyint )
BEGIN
DROP TEMPORARY TABLE IF EXISTS aTable;
IF _TableType = 1 THEN
SET #SQL_Statement :=
CONCAT(
'CREATE TEMPORARY TABLE aTable (',
'the_id bigint, ',
'the_column varchar(100) ',
') engine=INNODB',
';');
ELSE
SET #SQL_Statement :=
CONCAT(
'CREATE TEMPORARY TABLE aTable (',
'the_id bigint, ',
'the_other_column varchar(100) ',
') engine=INNODB',
';');
END IF;
PREPARE stmtCreateTable FROM #SQL_Statement;
EXECUTE stmtCreateTable;
DEALLOCATE PREPARE stmtCreateTable;
SET #SQL_Statement := NULL;
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS GetATable;
DELIMITER $$
CREATE PROCEDURE GetATable()
BEGIN
CALL CreateATable( 1 );
SELECT * FROM aTable;
CALL CreateATable( 2 );
SELECT * FROM aTable;
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS GetATable2;
DELIMITER $$
CREATE PROCEDURE GetATable2(_TableType tinyint)
BEGIN
CALL CreateATable( _TableType );
SELECT * FROM aTable;
END$$
DELIMITER ;
/*
Test execution script starts here
*/
-- Just CALL Create for one and Select
CALL CreateATable( 1 );
DESCRIBE aTable;
SELECT * FROM aTable;
CALL CreateATable( 2 );
DESCRIBE aTable;
SELECT * FROM aTable;
-- -> no errors
-- now CALL procedure to Create and Select from two different temp tables
CALL GetATable();
-- -> no errors
-- now CALL procedure to CREATE AND SELECT from ONE temp table definition using a parameter to select
CALL GetATable2(1);
CALL GetATable2(2);
-- Error Code: 1054. Unknown column 'mySchema.aTable.the_column' in 'field list'
I would expect that I can pass a parameter to a stored procedure to generate a temporary table, and return the records of that temporary table. Even if I call that same procedure multiple times with different parameters on the same session.
The actual results are that when the stored procedure is called to generate the temporary table with a different table structure, it returns this error complaining about the column missing from the temporary table created in the previous invocation of that same stored procedure.
Error Code: 1054. Unknown column 'mySchema.aTable.the_column' in 'field list'
The only way I have found to prevent this error is
a. ending the jdbc connection and ending the server session
b. recompiling one of the stored procedures in the call stack
Recompiling is not viable. And ending the session seems unreasonable.
This seems like a defect. But would be interested to find if there is some way to get this to work.
This seems like a bug and you can report it directly to the MariaDB team at MariaDB bugs database.
A temporary solution is to use a prepared statement in the stored procedure GetATable2 (my test on MariaDB 10.3.16 to use EXECUTE IMMEDIATE):
...
CREATE PROCEDURE `GetATable2`(`_TableType` TINYINT)
BEGIN
CALL CreateATable(`_TableType`);
-- SELECT * FROM `aTable`;
EXECUTE IMMEDIATE 'SELECT * FROM `aTable`';
END$$
...
See dbfiddle.

how can i call stored procedure from the function in mariadb?

i want to get count of no.of rows present in table which i pass at runtime to a function.
i have created a procedure and function to execute dynamic queries. function will not allow dynamic query because i am calling procedure from function.
that procedure having dynamic query.
///////procedure///////
CREATE PROCEDURE bizopsgolddev.`test1`(tbnm varchar(100))
begin
declare sql_text varchar(200);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SELECT CONCAT(sql_text, ' is not valid');
END;
set sql_text=concat('select count(*) from ',tbnm);
SET #SQL := sql_text;
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
end;
//////function//////
DROP FUNCTION IF EXISTS xyz;
CREATE FUNCTION `xyz`(tname varchar(100)) RETURNS int(11)
begin
declare val int;
call test1(tname);
return 1;
end;
if i execute this //select xyz('axpdc')// it should return rows count
can any one tell me how can i get count by passing table name to function(in mariadb only)
As I understand the question, the solution would be a function that returns the row count of a table with it's name passed to the function as a parameter.
I think this could be done by querying the information_schema database in MariaDB. A function could look like this:
CREATE DEFINER = 'yourUsername'#'192.168.%'
FUNCTION testDataBase.fn_GetRowCount(tableName VARCHAR(128))
RETURNS int(11)
BEGIN
-- This could be a parameter if need it to be.
DECLARE databaseName varchar(40) DEFAULT 'testDataBase';
DECLARE result int DEFAULT -1;
SELECT t.TABLE_ROWS INTO result
FROM information_schema.TABLES t
WHERE t.TABLE_NAME = tableName
AND t.TABLE_SCHEMA = databaseName;
RETURN result;
END
In order for this to work the user mentioned as the definer must have read privilege to the TABLES table in the information_schema database, otherwise you might get an error (tbh, I don't know if this is necessary).
There is a lot of useful information to be grabbed from the information_schema database.

I want to place this variable into a .db database through sqlite 3

I'm writing a lua program and created a variable for the value the user inputted into a text field. I want to place this variable into a .db database through sqlite 3. How do I show a variable in the insert query?
function addToDatabase()
-- Inserting Rows into Database
local insertQuery = [[INSERT INTO test VALUES
(NULL, ?, 'endOdomReading', ?, 'business', 'Middle Park', 'Logan', '32', '26.56');, (startOdomReading, date)]]
db:exec(insertQuery)
end
I'm not sure which library you use for SQLite3 access (I don't know Corona).
Here's an example using lsqlite3 (which I have renamed to sqlite3 -- no leading l):
function AddToDb(a,b) --insert rows into database using prepared statement
stmt:reset()
stmt:bind(1,a)
stmt:bind(2,b)
assert(stmt:step() == sqlite3.DONE)
end
db = sqlite3.open ':memory:'
db:exec 'create table xxx(value1,value2)'
stmt = db:prepare 'insert into xxx values(?,?)'
AddToDb('hello','world')
AddToDb('bye','now')
for rowid,a,b in db:urows 'select rowid,value1,value2 from xxx' do
print(rowid,a,b)
end
db:close()

Create and insert a row into the table in stored procedure

create or replace procedure sample
as
ID VARCHAR(20);
BEGIN
execute immediate
'CREATE GLOBAL TEMPORARY TABLE UPDATE_COLUMN_NO_TP
(
NAME VARCHAR2(256)
)';
INSERT INTO UPDATE_COLUMN_NO_TP
SELECT SRC_PK_COLUMNS.PK_KEY
FROM SRC_PK_COLUMNS
WHERE NOT EXISTS (
SELECT 1
FROM TGT_PK_COLUMNS
WHERE TGT_PK_COLUMNS.ID = SRC_PK_COLUMNS.ID);
END;
Error is:
The table is no exist.
So, I want a best solution for this scenario. In my stored procedure I have 10 temporary tables. All are all dynamic creations and inserts.
Table UPDATE_COLUMN_NO_TP not exists at compile time, so you got the error.
If you created a table dynamically, you should access it dynamically.
And pay attention to Mat's comment about essence of GTT.
execute immediate '
INSERT INTO UPDATE_COLUMN_NO_TP
SELECT SRC_PK_COLUMNS.PK_KEY
FROM SRC_PK_COLUMNS
WHERE NOT EXISTS (
SELECT 1
FROM TGT_PK_COLUMNS
WHERE TGT_PK_COLUMNS.ID = SRC_PK_COLUMNS.ID
)
';

How to drop multiple databases based on a prefix string

example_ or e_
I want to drop all databases that match the prefix e_, so that e_database1, e_database2 and so forth are dropped.
Commands that do not work:
mysql drop database e_%
mysql drop database e_*
I'm not looking for all the tables in a given database, but all the databases in a given MySQL server.
You could do this with a stored proc like this:
/* Start stored proc */
DELIMITER //
DROP PROCEDURE IF EXISTS db_clean_up //
CREATE PROCEDURE db_clean_up
(
)
BEGIN
declare done bit default false;
declare deleted varchar(255);
-- Drop DBs
DECLARE cur1 CURSOR FOR SELECT
SCHEMA_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME LIKE 'db_prefix%';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
createLoop: LOOP
FETCH cur1 INTO deleted;
IF done THEN
LEAVE createLoop;
END IF;
SET #query = CONCAT('DROP DATABASE `', deleted, '`;');
PREPARE stmt1 FROM #query;
EXECUTE stmt1;
END LOOP createLoop;
CLOSE cur1;
END //
delimiter ;
/* End stored proc */

Resources