c动态sql
有时需要在oracle
存储过程中执行动态sql
语句
,例如表名是动态的,或字段是动态的,或查询命令是动态的,可用下面的方法:
set
serveroutput
on
declare
n
number;
sql_stmt
varchar2(50);
t
varchar2(20);
begin
execute
immediate
'alter
session
set
nls_date_format=''yyyymmdd''';
t
:=
't_'
||
sysdate;
sql_stmt
:=
'select
count(*)
from
'
||
t;
execute
immediate
sql_stmt
into
n;
dbms_output.put_line('the
number
of
rows
of
'
||
t
||
'
is
'
||
n);
end;
如果动态sql
语句
很长很复杂,则可用包装.
create
or
replace
package
test_pkg
is
type
cur_typ
is
ref
cursor;
procere
test_proc
(v_table
varchar2,t_cur
out
cur_typ);
end;
/
create
or
replace
package
body
test_pkg
is
procere
test_proc
(v_table
varchar2,t_cur
out
cur_typ)
is
sqlstr
varchar2(2000);
begin
sqlstr
:=
'select
*
from
'||v_table;
open
t_cur
for
sqlstr;
end;
end;
/
在oracle
中批量导入,导出和删除表名以某些字符开头的表
spool
c:\a.sql
select
'drop
table
'
||
tname
||
';'
from
tab
where
tname
like
't%';
spool
off
@c:\a
㈡ ProC动态SQL EXEC SQL PREPARE sql FROM :c_sql;
(1)动态SQL1:
不能是查询(SELECT)语句,并且没有宿主变量.
用法:拼一句动态SQL语句,并用EXECUTE
IMMEDIATE执行,如:
EXEC
SQL
EXECUTE
IMMEDIATE
CREATE
TABLE
test
(test_col
VARCHAR2(4));
EXEC
SQL
EXECUTE
IMMEDIATE
INSERT
INTO
TABLE
test
('AAAA');
EXEC
SQL
EXECUTE
IMMEDIATE
DELETE
test
WHERE
test_col='AAAA';
(2)动态SQL2:
不能是查询(SELECT)语句,并且输入的宿主变量数目是知道的,
用法:拼一句动态SQL语句,用PREPARE,EXECUTE语句执行.
strcpy(sqlstring,
"DELETE
FROM
test
WHERE
test_col
=
:?");
EXEC
SQL
PREPARE
sqlproc
FROM
:sqlstring;
EXEC
SQL
EXECUTE
sqlproc
USING
:emp_number;
㈢ 静态的SQL 和动态的SQL有什么区别
静态 SQL:静态 SQL 语句一般用于嵌入式 SQL 应用中,在程序运行前,SQL 语句必须是确定的,例如 SQL 语句中涉及的列名和表名必须是存在的。静态 SQL 语句的编译是在应用程序运行前进行的,编译的结果会存储在数据库内部。而后程序运行时,数据库将直接执行编译好的 SQL 语句,降低运行时的开销。
动态 SQL:动态 SQL 语句是在应用程序运行时被编译和执行的,例如,使用 DB2 的交互式工具 CLP 访问数据库时,用户输入的 SQL 语句是不确定的,因此 SQL 语句只能被动态地编译。动态 SQL 的应用较多,常见的 CLI 和 JDBC 应用程序都使用动态 SQL。
㈣ proc*c中怎么使用动态sql语句
proc*c中怎么使用动态sql语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有。
㈤ pro *c是什么还有动态sql是什么
sql server
proc创建储存过程时的关键字
create proc 存储过程名
as
……
 
动态sql
可以理解为拼接的sql语句
如:
declare @sql varchar(max)
declare @id int
set @id = 123
set @sql = 'select * from aaa where id = ' + @id
exec(@sql)
 
这样的,根据不同情况拼接成不同的sql语句以及条件,这就是动态,可变的
㈥ C语言环境下如何使用动态SQL
你真是牛人呀。数据库类型那么多,有oraclemysqlDB2SQLSQLsevera。你使用的那种。
相对于来说我使用oracle多。
给你一个pro*c的操作实例吧
/ 定义符号常数
#define USERNAME "SCOTT"
#define PASSWORD "x"
#include <stdio.h>
// 说明SQLCA和ORACA
EXEC SQL INCLUDE SQLCA;
EXEC SQL INCLUDE ORACA;
// 启用ORACLE通讯区:ORACA=YES,使它能被使用
EXEC ORACLE OPTION (ORACA=YES);
// 说明SQL变量
EXEC SQL BEGIN DECLARE SECTION;
char* username=USERNAME;
char* password=PASSWORD;
VARCHAR sqlstmt[80];
int emp_number;
VARCHAR emp_name[15];
VARCHAR job[50],job1[50],job2[50];
float salary;
EXEC SQL END DECLARE SECTION;
main()
{
EXEC SQL WHENEVER SQLERROR GOTO sqlerror;
// 发生错误时,保存SQL语句至ORACA
oraca.orastxtf=ORASTFERR;
// 登录到ORACLE
EXEC SQL CONNECT :username IDENTIFIED BY :password;
printf("/nConnect to ORACLE./n");
// 构造动态SQL语句
sqlstmt.len=sprintf(sqlstmt.arr,"INSERT INTO EMP(EMPNO,ENAME,JOB,SAL)VALUES(:V1,:V2,:V3,:V4)");
// 显示SQL语句
puts(sqlstmt.arr);
// 用PREPARE语句分析当前的动态INSERT语句,语句名是S
EXEC SQL PREPARE S FROM :sqlstmt;
// 循环插表
for(;;)
{
printf("/nEnter employee number:");
scanf("%d",&emp_number);
if(emp_number==0)break;
printf("/nEnter employee name:");
scanf("%s",&emp_name.arr);
emp_name.len=strlen(emp_name.arr);
printf("/nEnter employee job:");
scanf("%s",&job.arr);
job.len=strlen(job.arr);
salary = 0; // With VC6, Missing this line will cause C Run-Time Error R6002.
printf("/nEnter salary:");
scanf("%f",&salary);
EXEC SQL EXECUTE S USING :emp_number,:emp_name,:job,:salary;
}
// 提交事务,退出ORACLE
EXEC SQL COMMIT RELEASE;
printf("/nHave a good day!/n");
exit(0);
sqlerror:
// 打印错误信息
printf("/n%.*s/n",sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc);
// 打印出错SQL语句
printf("/n/"%.*s.../"/n",oraca.orastxt.orastxtl,oraca.orastxt.orastxtc);
// 打印出错SQL语句所在行号及所在文件名
printf("on line %d of %.*s/n/n",oraca.oraslnr,
oraca.orasfnm.orasfnml,oraca.orasfnm.orasfnmc);
// 回滚事务,退出ORACLE
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL ROLLBACK RELEASE;
exit(1);
}
㈦ 静态SQL和动态SQL的区别和测试实例
所谓SQL的动态和静态,是指SQL语句在何时被编译和执行,二者都是用在SQL嵌入式编程中的。 
 静态SQL:在高级语言中,如果嵌入了SQL语句,而这个SQL语句的主体结构已经明确,例如在c的一段代码中有一个待执行的SQL“select * from t1 where c1>5”,在编译阶段,就可以将这段SQL交给数据库管理系统去分析,数据库软件可以对这段SQL进行语法解析,生成数据库方面的可执行代码,这样的SQL称为静态SQL,即在编译阶段就可以确定数据库要做什么事情。 
 动态SQL:如果嵌入的SQL没有明确给出,如在c中定义了一个字符数组类型的变量name:char name[32];,然后采用prepared Statement对象的execute方法去执行这个sql,该sql的值可能等于从文本框中读取的一个SQL或者从键盘输入的SQL,但具体是什么,在编译时无法确定,只有等到程序运行起来,在执行的过程中才能确定,这种SQL叫做动态SQL。例如每一种数据库软件都有能够执行SQL语句的界面,那个界面接收的SQL就是动态SQL,因为数据库厂商在做这个界面时,并不知道用户会输入哪些SQL,只有在该界面执行后,接收了用户的实际输入,才知道SQL是什么。 
 注意:在SQL中如果某些参数没有确定,如”select * from t1 where c1>? and c2#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
EXEC SQL INCLUDE SQLCA;
EXEC SQL INCLUDE SQLDA;
/*此函数属于静态SQL编程*/
int DBSelect_static(){
    EXEC SQL BEGIN DECLARE SECTION;
    char                _typename[32];
    short               _length;
    EXEC SQL END     DECLARE SECTION; 
    EXEC SQL  SELECT typename,length 
                        INTO :_typename,:_length
                        FROM syscat.columns 
                        WHERE tabname='SYSCOLUMNS' and colname='DEFAULT';
    printf("【typename:%s】【length:%d】\n",_typename,_length); 
}
/*此函数属于静态SQL编程:指定函数参数作为SQL语句的变量*/
int DBSelect_static_param(char *tbl_str,char *col_str){
    EXEC SQL BEGIN DECLARE SECTION;
    char                _typename1[32];
    short               _length1;
    EXEC SQL END     DECLARE SECTION; 
    EXEC SQL  SELECT typename,length 
                        INTO :_typename1,:_length1
                        FROM syscat.columns 
                        WHERE tabname='tbl_str' and colname='col_str';
    printf("【typename:%s】【length:%d】\n",_typename1,_length1);   
}
/*此函数属于动态SQL编程:SQL语句的结构是不确定的,需要根据用户的输入补全SQL语句*/
int DBUpdate_dynamic(){
    EXEC SQL BEGIN DECLARE SECTION;
    char        _address1[32];
    char        _tablename[32];
    char        _tmp[32];
    char        buf[256];
    EXEC SQL END     DECLARE SECTION;
    EXEC SQL SELECT count(address1) INTO :_tmp FROM cisaddressinfo WHERE customid='100000100000000000178';
    if(0==_tmp) {printf("Not Found!\n");return -1;}
    memset(buf,0x00,sizeof(buf));
    sprintf(buf,"update ");
    printf("Pls input : tablename ->");
    scanf("%s",&_tablename);
    strcat(buf,_tablename);
    strcat(buf," set address1=? where customid='100000100000000000178'");
    EXEC SQL PREPARE project FROM :buf; 
    if(sqlca.sqlcode) perror("PREPARE");
    printf("Pls input : address1 ->");
    scanf("%s",&_address1);
    EXEC SQL EXECUTE project USING :_address1;
    if(sqlca.sqlcode) perror("EXECUTE");
    EXEC SQL COMMIT WORK;
    if(sqlca.sqlcode) perror("COMMIT"); 
}
/*此函数属于动态SQL编程:使用sqlda数据结构组装复杂多变的动态SQL*/
int DBSelect_dynamic(){
    EXEC SQL BEGIN DECLARE SECTION;
  char      hostVarStmt[256];
    EXEC SQL END     DECLARE SECTION;   
    // 声明两个 SQLDA 指针,minsqlda 将是一个最小的 SQLDA 结构,用于 PREPARE 语句,
  // 此时结果集的字段数量未知,所以只需一个最小的 SQLDA,即包含 HEADER 和一个 SQLVAR 
  struct sqlda * minsqlda = (struct sqlda*)malloc(SQLDASIZE(1)); 
  struct sqlda * fulsqlda = NULL;   
  strcpy(hostVarStmt, "select WUID from workprocess where muid = '185001'");   
  // PREPARE 将填写 minsqlda 的 header,sqldabc 为 SQLDA 总长度,sqln 为 SQLVAR 数量,即字段数量
  EXEC SQL PREPARE STMT INTO :*minsqlda FROM :hostVarStmt;   
  // 根据从 minsqlda 中获取的长度,分配完整的 SQLDA 结构 fulsqlda,其中将包括合适数量的 SQLVAR 结构
  //结构sqlda的成员变量sqld返回select查询语句的字段的数目,可以根据此变量分配内存
  fulsqlda = (struct sqlda *)malloc(SQLDASIZE(minsqlda->sqld));   
  // 使用 DESCRIBE 语句,获取结果集中每个字段的描述信息,包括各字段的类型 (sqltype) 和长度 (sqllen) 
  EXEC SQL DESCRIBE STMT INTO :*fulsqlda; 
  int i;
  for(i=0;i<minsqlda->sqld;i++) 
  { 
    // 根据每个字段的长度,分配内存,将地址存储在对应 SQLVAR 的 sqldata 中
//    fulsqlda->sqlvar[i].sqldata=malloc(fulsqlda->sqlvar[i].sqllen);
    fulsqlda->sqlvar[i].sqldata=malloc(32);
    fulsqlda->sqlvar[i].sqlind=malloc(sizeof(short));
  } 
  // 声明游标
  EXEC SQL DECLARE c1 CURSOR FOR STMT; 
  EXEC SQL OPEN c1;  
  EXEC SQL WHENEVER not found goto no_more_data;
  // 读取记录,记录中每个字段的内容将写入 fulsqlda 中对应 SQLVAR 结构的 sqldata 指向的内存
  // EXEC SQL FETCH c1 USING DESCRIPTOR :*fulsqlda;  
  // 循环读取所有记录
  for (;;) 
  { 
    EXEC SQL FETCH c1 USING DESCRIPTOR :*fulsqlda; 
    for(i=0;i<minsqlda->sqld;i++){          
        printf("%d  %s\n",fulsqlda->sqlvar[i].sqltype,fulsqlda->sqlvar[i].sqldata);
        usleep(10000);  
    }
  }  
  return 0;
  no_more_data:
    printf("\nEND of Data\n");
    free(minsqlda);
    free(fulsqlda);
        EXEC SQL CLOSE c1;
        return 0;
}
int main(){
    /*连接数据库*/
    EXEC SQL CONNECT TO ezeelink USER ezeelink USING EA704075ezeelink; 
    DBSelect_static();
    DBSelect_static_param("SYSCOLUMNS","DEFAULT");
    DBUpdate_dynamic();
    DBSelect_dynamic(); 
  no_more_data:
    ;   
    return 0;   
}
案例输出结果如下: 
 【typename:VARCHAR】【length:254】 
 【typename:VARCHAR】【length:254】 
Pls input : tablename ->cisaddressinfo 
 Pls input : address1 ->ShangHai 
 452  cis505 
 452  cis506 
 452  pub806 
 452  ips007 
 452  ips032 
 452  dps302
END of Data
注意: 
 如果使用动态SQL编程编写select查询语句并保存结果,需要使用sqlda数据结构的,同时使用SQL的特性和功能,如:PREPARE ,EXECUTE ,DESCRIBE , DECLARE CURSE C1 FOR … , OPEN CURSE , CLOSE CURSE ….等等 
 建议: 
 动态SQL适用于表名及查询字段名未知的情况。在已知查询字段名及表名的情况下,使用动态SQL(字符串拼接方式)会增加硬解析的开销,在这种情况下,建议使用静态SQL,这样可以提高执行效率。在过程过程用拼凑的动态sql效率并不高,有时候还不如程序直接传递sql.静态SQL是前置编译绑定,动态SQL是后期执行时才编译绑定
㈧ C#中使用动态sql问题 新手 急!!!!!!!!!!满意加50分!!!!!!
用什么动态sql啊,这种情况下,把用户输入的的字段写在C#的sql语句中就好了,又不是要你在sql中来实现动态字段查询。
所谓的动态sql,说简单点就是在sql查询中,以字符串的方式组合查询sql语句,最后使用exec关键字来执行这个组合的查询字符串:
declare @sql varchar(500)
set @sql='select top 1 from master.sys.objects'
exec (@sql)
就是一段简单的动态sql
㈨ 动态SQL中的重复占位符如何与绑定变量进行
BEGIN calc_stats(:x, :x, :y, :x); END 是一个PL/SQL 代码段,而非 insert into t6 (a,b,c) values (:x,:y,:x) 这样的DML,标准SQL语句。
在EXECUTE IMMEDIATE 中,利用USING语句绑定变量时,Oracle遵循针对PL/SQL存储过程使用占位符名称匹配的原则,而针对SQL语句则采用占位符位置匹配的原则。
PL/SQL 用户指南与参考 中的 例子如下:
动态SQL语句中的占位符与USING子句中的绑定参数是位置关联的,而不是名称关联。所以,如果在SQL语句中同样的占位符出现两次或多次,那么,它的每次出现都必须与一个USING子句中的绑定参数相关联。例如下面的动态字符串:
sql_stmt := 'INSERT INTO payroll VALUES (:x, :x, :y,  :x)';
我们可以为动态字符串编写对应的USING子句:
EXECUTE IMMEDIATE  sql_stmt USING a, a, b, a;
但 是,动态PL/SQL块中只有唯一的占位符才与USING子句中的绑定参数按位置对应。所以,如果一个占位符在PL/SQL块中出现两次或多次,那么所有 这样相同的占位符都只与USING语句中的一个绑定参数相对应。比如下面的例子,第一个占位符(x)与第一个绑定参数(a)关联,第二个占位符(y)与第 二个绑定参数(b)关联。
DECLARE
a   NUMBER := 4;
b   NUMBER := 7;
BEGIN
plsql_block     := 'BEGIN calc_stats(:x,  :x, :y, :x); END';
EXECUTE IMMEDIATE plsql_block
USING a, b;
...
END;
---------------------------------------------------------------------------------------------
CREATE TABLE T1 (N1 NUMBER, N2 NUMBER,N3 NUMBER,N4 NUMBER);
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO T1(N1,N2,N3,N4) VALUES (:N1,:N2,:N2,:N1)' USING 1,2;
END;
/
*
ERROR at line 1:
ORA-01008: not all variables bound
ORA-06512: at line 2
BEGIN
EXECUTE IMMEDIATE 'BEGIN INSERT INTO T1(N1,N2,N3,N4) VALUES (:N1,:N2,:N2,:N1); END;' USING 1,2;
END;
/
PL/SQL procere successfully completed.
SELECT * FROM T1;
N1         N2         N3         N4
---------- ---------- ---------- ----------
1          2          2          1
----------------------------------------------
