Pro C dynamic SQL query - sql

I have to execute the following query using Pro C to get the output and den display the output to the user.
i tried the following code snippet:
int count=0;
char query1[100]="select count(code) from customer where customer_type='a';";
EXEC SQL ALLOCATE DESCRIPTOR 'out' ;
EXEC SQL PREPARE statement FROM :query1 ;
EXEC SQL DESCRIBE OUTPUT statement USING DESCRIPTOR 'out' ;
EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE = :data_type,
LENGTH = :data_len, DATA = :count ;
EXEC SQL DECLARE c CURSOR FOR statement ;
EXEC SQL OPEN c ;
EXEC SQL FETCH c INTO DESCRIPTOR 'out' ;
EXEC SQL GET DESCRIPTOR 'out' VALUE 1 :count = DATA;
EXEC SQL CLOSE c ;
printf("%-8d ",count);
but the output i get is always 0.
How shall i proceed to get the proper output??
can anyone help pls...

It is quite possible you have some errors in there that arn't getting noticed.
Use the EXEC SQL WHENEVER to get some error checking going on.
The one thing that jumps out at me is the semicolon at the end of the query1 value. If I recall correctly, Pro*c will barf on it.

I would strongly recommend against using this method of Pro*C dynamic SQL (Oracle dynamic SQL method 4) unless you can possibly avoid it.
The only case you should need to use this method is when you are using dynamically generated SQL and you don't know how many host variables will be used. E.g. You don't know how many columns will be in the SELECT clause.
A fully fledged example of using Oracle dynamic SQL method 4 can be found at http://docs.oracle.com/cd/B28359_01/appdev.111/b28427/pc_15ody.htm#i7419.

Related

DB2 SQL considers IF ELSE condition a DDL statement?

I am trying to use a simple IF ELSE query to test a feature with DB2 SQL. However when I attempt to execute it, I run into an error stating that I am not allowed to execute DDL statements.
What is throwing me off is that as far as I know, only database structure altering statements are considered DDL statements.
What gives?
Code:
IF 'True' = 'True' THEN
SELECT * FROM RM_TRANSACTION
FETCH FIRST 2 ROWS ONLY
FOR READ ONLY WITH UR
ELSE
SELECT * FROM RM_TRANSACTION
FETCH FIRST 4 ROWS ONLY
FOR READ ONLY WITH UR
END IF
https://imgur.com/a/58RYjpu
The problem is that you can’t ‘select to nowhere’ in a compound statement in DB2. Db2 CLP can return you the result set of a single sql statement, but it doesn’t try to do the same for select statements in a compound statement.
If you want to print the result set from a select statement in a compound statement, you can, for example, declare a cursor, fetch it in a loop, and use dbms_output.put_line calls to print the values of variables.

PLSQL Execute Immediate with Dynamic Using

I am dynamically building a search query with bind variables with at least 1 and at most 7 different potential criteria. I know I can do this -
EXECUTE IMMEDIATE sql USING bind_var1, bind_var2 or
EXECUTE IMMEDIATE sql USING bind_var3, bind_var5, bind_var7.
Is it possible to include the bind variables within the sql?
sql = 'SELECT * FROM table WHERE id = :bind_var1 AND name = :bind_var2 USING bind_var1, bind_var2'
and do
EXECUTE IMMEDIATE sql?
I want and need to dynamically build the USING piece instead of writing a lot of IF THEN statements.
According to your tags, I assume this will be used inside some kind of PL/SQL block. So, maybe are you looking for the open for statement.
This allows you to get a cursor on an dynamic query:
sql := 'SELECT * FROM table WHERE id = :bind_var1 AND name = :bind_var2';
open my_cursor for sql using bind_var1, bind_var2';
-- do whatever you need with your cursor
your USING bind_var1, bind_var2 pice of code should be out side os your sql string and come at the end of execute immediate statement and also for select senarios try to use dynamic sql for select with a cursor unless you want to select into a variable

error: too many many input arguments matlab

I am trying to execute a Sql query in matlab. The sql uses 'select' command for selecting a particular row using a columnname which matches a value that is stored in variable given in the following code.
When I execute this , I get an error : Error using ==> database.exec Too many input arguments.
q=value;%computed value.
conn1=database('Dbname','','');
fna=exec(conn1,'select * from table1 where ImageName="',q,'"');
fna=fetch(fna); fda=fna.data;
You are passing four input arguments, the last three ones must be concatitated to one sql command.
sqlquery=['select * from table1 where ImageName="',q,'"'];
fna=exec(conn1,sqlquery);
in the matlab manual it says that exec has the following syntax:
curs = exec(conn,sqlquery)
curs = exec(conn,sqlquery,qTimeOut)
You have four parameters in the exec functions, that's what the error means!

Can we use a host-variable as table name in SELECT query?

I'm experimenting with Pro*C code.
I have 3 tables emp, mgr, all; All 3 tables contain emp_id and emp_name. I tried the below code it is giving me error. Please let me know if it is possible?
const char table_name[3]={'emp','mgr','all'}
int counter = 0;
while(counter < 3)
{
. . .
EXEC SQL SELECT emp_name INTO :ename
From :table_name[counter++]
where emp_id=:emp_id;
}
Can we use variables for SELECT and FROM ?
This is called Dynamic SQL:
Use this info:
Dynamic SQL
While embedded SQL is fine for fixed applications, sometimes it is important for a program to dynamically create entire SQL statements.
With dynamic SQL, a statement stored in a string variable can be issued.
PREPARE turns a character string into a SQL statement, and EXECUTE executes that statement. Consider the following example.
char *s = "INSERT INTO emp VALUES(1234, 'jon', 3)";
EXEC SQL PREPARE q FROM :s;
EXEC SQL EXECUTE q;
Alternatively, PREPARE and EXECUTE may be combined into one statement:
char *s = "INSERT INTO emp VALUES(1234, 'jon', 3)";
EXEC SQL EXECUTE IMMEDIATE :s;
Source: http://infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html
No, we can't use a host-variable to supply a table-name to a static SQL statement in Pro*C.
To quote Oracle Pro*C Programmer's Guide for Oracle 11.2g:
You cannot use input host variables to supply SQL keywords or the names of database objects. [..] If you need to change database object names at runtime, use dynamic SQL. See also Chapter 13, "Oracle Dynamic SQL".
In Pro*C Oracle provides different methods to execute SQL statements. The main distinction is between static and dynamic methods. And for dynamic there are several sub-methods that allow different degrees of freedom.
A static SQL statement is not 100% static - you can use input/output host-variables in where clause expressions (as operands), to supply values in insert statements, as select targets, etc. But not to specify table names. This is 'too dynamic' for static embedded SQL.
Note that you can still use host-variables in your dynamically prepared SQL statements. This is recommended to avoid SQL injection issues and increase performance (when a statement is executed several times).
Example (uses Oracle Dynamic SQL method 3):
const char *table_name[3] = {"emp", "mgr", "all"};
unsigned table_name_size = 0;
unsigned i = 0;
for (i = 0; i<table_name_size; ++i) {
char stmt[128] = {0};
snprintf(stmt, 128,
"SELECT emp_name "
" FROM %s "
" WHERE "
" emp_id = :emp_id",
table_name[i]);
EXEC SQL PREPARE emp_stmt FROM :stmt;
// check sqlca.sqlcode ...
EXEC SQL DECLARE emp_cursor CURSOR FOR emp_stmt;
EXEC SQL OPEN emp_cursor USING :emp_id;
// check sqlca.sqlcode ...
EXEC SQL FETCH emp_cursor INTO :ename;
// check sqlca.sqlcode ...
EXEC SQL CLOSE emp_cursor;
// check sqlca.sqlcode ...
// ...
}

check for zero rows in select query

My C program has an embedded sql query. This program runs on windows and queries the oracle database.
The query is similar to EXEC SQL SELECT ...
I need to add here a check to know if the query returns zero rows.
Basically I want to set a local valiable to know my query has returned no rows and
handle this condition accordingly.
How can I add it. I know that EXISTS statement can be used. But I am not getting
how do I use it in embedded sql.
Thanks for any help.
Use the sqlca struct
EXEC SQL include "sqlca.h"
#define NO_ROWS_FOUND (sqlca.sqlcode==1403)
EXEC SQL BEGIN DECLARE SECTION;
int val=0;
short ind=0;
EXEC SQL END DECLARE SECTION;
EXEC SQL
select value
int :val :ind
from mytable where rownum=1;
if(NO_ROWS_FOUND)
printf("No rows found\n");
Use SELECT COUNT(*) FROM ... and compare result to 0.