prepare:標識動態sql的
因為1.用變量做表名: 簡單的用set或者declare語句定義變量,然后直接作為sql的表名是不行的,mysql會把變量名當作表名。在其他的sql數據庫中也是如 此,mssql的解決方法是將整條sql語句作為變量,其中穿插變量作為表名,然后用sp_executesql調用該語句。僅對procedure有 效,function不支持動態查詢
最近job調度平台的項目要核對數據,需要編寫一個存儲過程來獲取生產庫上相關表的總記錄條數,
通過與測試庫上的數據條數進行對比來進行大致的核對。由於我之前沒寫過DB2的過程,所以寫起來
比較費勁,不過最終還是完成了。
具體是這樣的:我們先通過SQL在生產上查找出與項目相關的表,在存儲過程中聲明一個臨時表來
存放這些表名,並用另一個字段來存儲各表的記錄條數;
然后,聲明一個游標來獲取所有的表名(這里游標不要從臨時表里來獲取數據,在臨時表聲明前就
要聲明游標,游標數據同臨時表一樣通過SQL來獲取);
接着就是通過游標來生成動態的SQL。在DB2中動態SQL中包含SELECT或者VALUES是不能夠直接執行
的,這也是一直困擾我的地方。在網上看了好多相關的資料,經過多次嘗試,最終找到了解決辦法。
要執行包含SELECT或者VALUES的動態SQL 語句,要做以下幾步:
1.聲明一個存放動態SQL的變量 v_sql
2.聲明一個statement類型的變量 v_stmt
3.為statement變量聲明一個游標 c2
4.寫好動態SQL語句 set v_sql='select count(*) from dbo.'||v_1;--(v_1為表名)
5.prepare v_stmt from v_sql
6.打開游標c2,fetch c2 into v_count; 關閉游標
最后用v_count的值來更新臨時表,進行數據導出;
call sysproc.admin_cmd('export to /home/db2inst1/validate/validate.csv of del select * from session.tmp');
導出數據時,我想直接導出到本地,剛一開始就寫了個本地的路徑,結果報錯了,后來才知道要一個遠程服務器
的路徑才可以,並且用戶要有寫入的權限。
declare v_sql varchar(4000) default '';--動態sql 可以看到這里是聲明了一個變量,字符串,默認值是空字符串 --程序開始 --表-- if upper(v_lx) = 'T' then if exists(select 1 from sysibm.tables where table_schema = 'PAS' and table_name= ltrim(rtrim(replace(upper(v_ccmc),'PAS.','')))) then set v_sql='drop table '||v_ccmc; prepare s1 from v_sql; 而在這里聲明了這個變量是一個動態sql,然后就去執行了,不如不聲明的話就有可能會出現把變量本身作為參數了 execute s1; end if; end if;
PS:說下我個人的大白話理解
動態sql:
假設我們聲明兩個個變量 declare v_sql varchar(4000) default '';(動態sql語句,默認值為空字符串),declare v_cmcc varchar(40);(傳進來的值為jxdx_ckzh)
,給變量賦值set v_sql='drop table'||v_ccmc
那么我們用execute去執行這條sql 執行的語句就是 drop table jxdx_ckzh
不聲明為動態sql的話:
直接用execute去執行v_sql :excute v_sql
執行的就是 drop table v_cmcc 刪除的就是這個表