c++ how to make two statement sql work with OLEDB? - c++

I have the following SQL statement:
USE "ws_results_db_2011_09_11_09_06_24";SELECT table_name FROM INFORMATION_SCHEMA.Tables WHERE table_name like 'NET_%_STAT' order by table_name
I am using the following C++ code to execute it:
IDBCreateCommandPtr spDBCreateCommand = GetTheDBCreateCommandPointer();
ICommandTextPtr spCommandText;
spDBCreateCommand->CreateCommand(NULL, IID_ICommandText, reinterpret_cast<IUnknown **>(&spCommandText));
spCommandText->SetCommandText(DBGUID_SQL, GetTheQueryText());
IRowsetPtr spRowset;
spCommandText->Execute(NULL, IID_IRowset, NULL, NULL, reinterpret_cast<IUnknown **>(&spRowset));
RowHandles hRows(spRowset, 0);
ULONG rowCount;
ULONG maxRowCount = 1;
spRowset->GetNextRows(DB_NULL_HCHAPTER, 0, maxRowCount, &rowCount, hRows.get_addr());
Two notes:
Error handling is omitted for brevity
RowHandles implements the RAII concept for HROW *
Anyway, I fail to execute the two SQL statements. What happens is that spCommandText->Execute returns S_OK, but sets spRowset to NULL.
If I execute the same spCommandText->Execute the second time (by moving back the instruction pointer during the debugging session), then a valid IRowset pointer is returned - I successfully obtain the correct column information using it. But spRowset->GetNextRows sets rowCount to 0 and returns DB_S_ENDOFROWSET - no luck.
The code is working fine when I execute a single SQL statement.
What am I doing wrong?
Thanks.

It is up to the client to split the sql commands - isql does this on the ; ie you are asking for two commands the use and the select.
So the fix is to do the two commands by separate sets of CreateCommands and execute.
Also note in this case you can do the commands as one SQL statement
SELECT table_name FROM ws_results_db_2011_09_11_09_06_24.INFORMATION_SCHEMA.Tables
WHERE table_name like 'NET_%_STAT'
order by table_name

Related

How do I create a table for all tables in MySQL

I’m using MySQL for C++ and I want to create a new table for all the tables in my second database. The code I have now is:
CREATE TABLE new_table LIKE original_table;
INSERT INTO new_table SELECT * FROM original_table;
I want to this to work like a loop where all the tables and data in those tables are created for every table and piece of data there is in my second database. Can someone help me?
We can use a stored procedure to do the job in a loop. I just wrote the code and tested it in workbench. Got all my tables(excluding view) from sakila database to my sakila_copy database:
use testdb;
delimiter //
drop procedure if exists copy_tables //
create procedure copy_tables(old_db varchar(20),new_db varchar(20))
begin
declare tb_name varchar(30);
declare fin bool default false;
declare c cursor for select table_name from information_schema.tables where table_schema=old_db and table_type='BASE TABLE';
declare continue handler for not found set fin=true;
open c;
lp:loop
fetch c into tb_name;
if fin=true then
leave lp;
end if;
set #create_stmt=concat('create table ',new_db,'.',tb_name,' like ',old_db,'.',tb_name,';') ;
prepare ddl from #create_stmt;
execute ddl;
deallocate prepare ddl;
set #insert_stmt=concat('insert into ',new_db,'.',tb_name,' select * from ',old_db,'.',tb_name,';');
prepare dml from #insert_stmt;
execute dml;
deallocate prepare dml;
end loop lp;
close c;
end//
delimiter ;
create database sakila_copy;
call testdb.copy_tables('sakila','sakila_copy');
-- after the call, check the tables in sakila_copy to find the new tables
show tables in sakila_copy;
Note: As I stated before, only base tables are copied. I deliberately skipped views, as they provide logical access to tables and hold no data themselves.

Teiid execute immediate gives a parsing error when executing long queries

I'm using virtual procedures to expose a REST API using teiid. In my virtual procedure i am using execute immediate to execute SQL queries which takes input parameters from the virtual procedure as filters to the where clause (dynamic where cluase). This works fine for small select queries but when the query length is above a particular length it gives an parsing error.
Is there any solution for this problem?
Is there any alternative way of implementing dynamic where clauses in my SQL query?
Lets assume that the fallowing query has around 4000 characters. this works fine.
CREATE VIRTUAL PROCEDURE GetVals(IN filters string) RETURNS (json clob) OPTIONS (UPDATECOUNT 0, "REST:METHOD" 'GET', "REST:URI" 'get_vals')
AS
BEGIN execute immediate
'SELECT JSONOBJECT(JSONARRAY_AGG(JSONOBJECT(
col1,
col2,
col3,
col4,
col5,
col6,
....
....
)) as "data"
) as json FROM(
SELECT SUM((CASE
WHEN ((CASE
.....
....
.....
FROM ex_table AS ex
JOIN table1
ON ...
.....
WHERE a=b AND ' || filters || '
GROUP BY col)
) AB';
END
But as soon as I add more lines into above SQL query then it give an parsing error login an arbitrary line. There is nothing wrong with the syntax of my query. The only change I make is the length of the query adding more lines into it(eg. In my SELECT statement If I select onemore extra column this gives an parsing error)This happens only when I am using execute immediate to execute queries
What version or Teiid are you using? And what is your parsing exception?
If it is due to truncation, then you'll need to use a 9.1 or later release, which allows for longer evaluated sql strings - https://issues.jboss.org/browse/TEIID-4376

mysql.connector, multi=True, sql variable assignment not working

SQL code (all in one file that is eventually saved in the python variable "query"):
select #dtmax:=DATE_FORMAT(max(dt), '%Y%m') from table_A;
delete from table_B where DATE_FORMAT(dt, '%Y%m')=#dtmax;
Does mysql-connector allow the use of variable assignment like I've done in the query above. i.e. take the value of max(date) from TABLE_A and delete everything with that date from TABLE_B.
python code:
c = conn.cursor(buffered=True)
c.execute(query, multi=True)
conn.commit()
conn.close()
All I know is that the 2nd SQL statement doesnt execute.
I can copy and paste the SQL code into Toad and run it there without any problems but not through mysql.connector library. I would have used pandas but this is legacy script written by someone else and I don't have time to re-write everything.
I kindly appreciate some help.
When you use multi=True, then execute() will return a generator. You need to iterate over that generator to actually advance the processing to the next sql statement in your multi-statement query:
c = conn.cursor(buffered=True)
results = c.execute(query, multi=True)
for cur in results:
print('cursor:', cur)
if cur.with_rows:
print('result:', cur.fetchall())
conn.commit()
conn.close()
cur.with_rows will be True if there are results to fetch for the current statement.
This is all described in the documentation of MySQLCursor.execute()

SQL Error ORA-01002 not autocommit and loop

I'm using pro c/c++ in a unix environment. Inside a c function I create a simple select statement which is not inside a loop and autocommit is disabled.
This is the dynamic sql;
char sql_statement[200];
int num1, num2;
...
snprintf(sql_statement, sizeof(sql_sattement), "select column1, column2 from '%s' where num = '%d' and code_cfg = '%d'", "customer", 0, 0);
exec sql prepare instruction_to_execute from :sql_statement;
exec sql declare crs cursor for instruction_to_execute;
exec sql open crs;
exec sql fetch crs into :num1, :num2;
...
Executing this code gives me ORA-01002 error. As I said before, this code is not inside a loop and autocommit is off.
But if I write this code statically, works fine. Below the code:
EXEC SQL
SELECT column1, column2
INTO :num1, :num2
FROM CUSTOMER
where num = 0
AND code_cfg = 0;
SQL instruction is simple. For my understanding this code should be executed fine.
In SO I found some answers:
ORA-01002: fetch out of sequence C++
ORA-01002: fetch out of sequence
Hibernate error “ORA-01002” when persisting entity with custom Sequence Generator
ORA-01002: fetch out of sequence
java.sql.SQLException: ORA-01002: fetch out of sequence

Empty blob insert query in ODBC c ++ (oracle)

I need to insert a blob in o oracle database. I am using c++ and ODBC library.
I am stucked at the insert query and update query .It is abstract for me how to make an blob insert query.
I know how to make an query for a non blob column.
My table structure is :
REATE TABLE t_testblob (
filename VARCHAR2(30) DEFAULT NULL NULL,
apkdata BLOB NULL
)
I found an exemple on insert and update :
INSERT INTO table_name VALUES (memberlist,?,memberlist)
UPDATE table_name SET ImageFieldName = ? WHERE ID=yourId
But these structure of querys or abstract to me . What should memberlist be ? why is there "?" where are the values to be inserted ?
Those question marks means that it is PreparedStatement. Such statements are good for both server and client. Server has less work because it is easier to parse such statement, and client do not need to worry about SQLInjection. Client prepares such query, builds buffer for input values and calls it.
Also such statement is executed very quick compared to "normal" queries, especially in loops, importing data from csv file etc.
I don't know what ODBC C++ library you use while ODBC is strictly C library. Other languages like Java or Python can use it too. I think the easiest is example in Python:
cursor = connection.cursor()
for txt in ('a', 'b', 'c'):
cursor.execute('SELECT * FROM test WHERE txt=?', (txt,))
Of course such PreparedStatement can be used in INSERT or UPDATE statements too, and for your example it can look like:
cursor.execute("INSERT INTO t_testblob (filename, apkdata) VALUE (?, ?)", filename, my_binary_data)