日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

oracle 拼接sql 日期,动态SQL对日期处理注意事项

發(fā)布時間:2025/3/15 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 oracle 拼接sql 日期,动态SQL对日期处理注意事项 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

如果一定要是動態(tài)SQL,一定要將日期類型用||拼起來,見下列寫法,紅色的是錯的,下面的才對,兩次類型轉(zhuǎn)換,但是沒有什么必要

--要么用綁定變量綁定date類型,要么靜態(tài)sql,不要兩次轉(zhuǎn)換,直接拼日期前后不加單引號還會報錯。

SQL> DECLARE

2 ? v_date date := sysdate;

3 ? v_cnt number := 0;

4 ? v_sql varchar2(100);

5 ?BEGIN

6 ? ?v_sql := 'SELECT COUNT(*) FROM USER_OBJECTS WHERE CREATED<='||v_date;

7 ? ?DBMS_OUTPUT.PUT_LINE(v_sql);

8 ? ?v_sql := 'SELECT COUNT(*) FROM USER_OBJECTS WHERE CREATED<='||chr(39)||v_date||chr(39);

9 ? ? ?DBMS_OUTPUT.PUT_LINE(v_sql);

10 ? ?EXECUTE IMMEDIATE v_sql INTO v_cnt;

11 ? ? ? ?DBMS_OUTPUT.PUT_LINE(v_cnt);

-- v_sql := 'SELECT COUNT(*) FROM USER_OBJECTS WHERE CREATED<=TO_DATE('''||v_date||''',''dd-mon-yy'')';

-- ? DBMS_OUTPUT.PUT_LINE(v_sql);

12 ?END;

13 ?/

SELECT COUNT(*) FROM USER_OBJECTS WHERE CREATED<=04-1月 -11

SELECT COUNT(*) FROM USER_OBJECTS WHERE CREATED<='04-1月 -11'

1810

PL/SQL procedure successfully completed

DROP TABLE t;

CREATE TABLE t(p1 DATE)

PARTITION BY RANGE(p1)

(PARTITION p0 VALUES LESS THAN ?( TO_DATE ('20110816', 'YYYYMMDD')) ?TABLESPACE USERS);

所以:

1.對非DDL,應(yīng)該要使用綁定變量,如果綁定變量適合的話

2.DDL,用不了綁定變量,必須to_date拼湊

DECLARE

p1 ? DATE := TO_DATE ('20110817', 'YYYYMMDD');

BEGIN

EXECUTE IMMEDIATE 'alter session set nls_date_format=''yyyymmdd''';

FOR i IN 1 .. 2

LOOP

EXECUTE IMMEDIATE

'alter table t add partition p'

|| TO_CHAR (p1, 'YYYYMMDD')

|| ' ?VALUES LESS THAN ( TO_DATE('''

|| p1

|| ''',''yyyymmdd'')) ?TABLESPACE USERS';

p1 := p1 + 1;

END LOOP;

END;

/

--不用設(shè)nls_date_format,因為兩次轉(zhuǎn)換的nls_date_format一樣,直接to_date,因為自動轉(zhuǎn)換的字符串沒有引號,需要補上引號

DECLARE

p1 ? DATE := TO_DATE ('20110817', 'YYYYMMDD');

BEGIN

FOR i IN 1 .. 2

LOOP

EXECUTE IMMEDIATE

'alter table t add partition p'

|| TO_CHAR (p1, 'YYYYMMDD')

|| ' ?VALUES LESS THAN ( TO_DATE('''

|| p1

|| ''')) ?TABLESPACE USERS';

p1 := p1 + 1;

END LOOP;

END;

/

--甚至可以去掉to_date,自動轉(zhuǎn)為目標(biāo)類型,但是要補引號

DECLARE

p1 ? DATE := TO_DATE ('20110817', 'YYYYMMDD');

BEGIN

DBMS_OUTPUT.put_line( ? ? 'alter table t add partition p'

|| TO_CHAR (p1, 'YYYYMMDD')

|| ' ?VALUES LESS THAN ( '''

|| p1

|| ''') ?TABLESPACE USERS');

END;

/

也可以對p使用顯示轉(zhuǎn)為字符串,和上面一樣

'alter table t add partition p'

|| TO_CHAR (p1, 'YYYYMMDD')

|| ' ?VALUES LESS THAN ( TO_DATE('''

|| TO_CHAR(p1,'YYYY-MM-DD')

|| ''',''YYYY-MM-DD'')) ?TABLESPACE USERS'

再看一個典型的拼湊日期的錯誤。

我常常看到別人不使用綁定變量,采用拼湊的方式傳入日期類型,比如:

declare

vname varchar2(10):='dd';

v_sql varchar2(4000);

vcnt number;

v_date date:=sysdate;

begin

v_sql:='select count(*) from test where birth='||v_date; --這里要出錯

dbms_output.put_line(v_sql);

execute immediate v_sql into vcnt;

dbms_output.put_line(vcnt);

end;

這里又出什么錯呢?請看打印出的語句是什么?

select count(*) from test where birth=08-5月 -10

原來在運行期,如果采用||date,那么日期自動根據(jù)session日期設(shè)置參數(shù)轉(zhuǎn)換為字符串,而字符串連接不自動加引號,所以就變成上面的了,丟失了引號,自動轉(zhuǎn)換也失效,語句錯誤了,如果你非要那樣做,只能

1. ? ? ? ?將v_date轉(zhuǎn)為字符串,帶引號的,然后讓其自動轉(zhuǎn)換,如: ?v_sql:='select count(*) from test where birth='''||v_date||''''; ?當(dāng)然也可以使用to_date,如

v_sql:='select count(*) from test where birth=to_date('''||v_date||''')';

不需要nls_date_format設(shè)置,因為兩次轉(zhuǎn)換的格式一樣.

也可以顯示轉(zhuǎn)換,代替oracle自動轉(zhuǎn)換v_sql:='select count(*) from test where birth='''||to_char(v_date)||'''';

最完整的全部顯示轉(zhuǎn)換

v_sql:='select count(*) from test where birth=to_date('''||to_char(v_date,'yyyymmdd')||''',''yyyymmdd'')';

2. ? ? ? ?DDL用不了綁定變量,只能使用1的方法,對非DDL,要用綁定變量,解決這個問題,一般起到軟解析效果。

以上是典型的拼湊導(dǎo)致的程序難以編寫而且容易出錯的例子,如果采用綁定變量的方式,以上問題全可迎刃而解。

也說明了一點,綁定變量不光使我們的SQL反復(fù)執(zhí)行的效率更高,在存儲過程的動態(tài)SQL里,綁定變量也會使我們減少錯誤的發(fā)生,更容易地進行編程(存儲過程的靜態(tài)SQL自動綁定,達到軟解析或軟軟解析的效果,當(dāng)然動態(tài)SQL也可能軟或軟軟解析)

不加to_date,發(fā)生2次轉(zhuǎn)換

第1次,v_date是date類型,但是用||運算,變?yōu)樽址?/p>

第2次,||兩邊加了引號,但是birth是date類型,又把字符串轉(zhuǎn)為date類型

因為這兩次轉(zhuǎn)換的格式和環(huán)境都一樣的,所以可以自動轉(zhuǎn)來轉(zhuǎn)去,當(dāng)然可讀性不是很好

總結(jié)

以上是生活随笔為你收集整理的oracle 拼接sql 日期,动态SQL对日期处理注意事项的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。