在SQL SERVER 2000上,讀取一段OPENQUERY SQL,資料來源為informix 11.50,ODBC為IBM INFORMIX 3.82 32BIT。
select * from openquery(testdb,'select * from testtable')出現以下錯誤。
OLE DB Provider 'MSDASQL' 提供資料行 'colxxx' 無效的中繼資料 (Metadata)。The scale exceeded the precision.
來源資料表中,有一欄位colxxx的型態 為decimal(14,0),透過OPENQUERY讀取時,有上述錯誤。
解決方法有二個
1.在SQL SERVER 2000所在主機ODBC,於Advanced頁籤中勾選Describe Decimal Floating Point as SQL_REAL/SQL_DOUBLE。
2.將SQL改寫如下,select
* from openquery(ifx220 'select colxxx::integer as colxxx from testtable'),先轉型為SQL
SERVER可接受的欄位型態。
2018年7月18日 星期三
2018年2月22日 星期四
informx setnet32 could not open the registry
一般安裝好INFORMIX ODBC DRIVER後,只要在控制台\所有控制台項目\系統管理工具下的ODBC 資料來源 (32 位元) 設定好連線應該就OK。
但今天在一台WINDOWS 10的電腦重安裝ODBC且也設定好連線資訊後並測試連線正常後,使用SQLDBX工具時,卻一直無法正常連線。
當利用Informix setnet32設定時,也一直顯示could not open the registry 的提示訊息。
解決方法:
在 Environment頁籤,將INFORMIXSQLHOSTS清空後,就可順利設定Server及Host Information了。
但今天在一台WINDOWS 10的電腦重安裝ODBC且也設定好連線資訊後並測試連線正常後,使用SQLDBX工具時,卻一直無法正常連線。
當利用Informix setnet32設定時,也一直顯示could not open the registry 的提示訊息。
解決方法:
在 Environment頁籤,將INFORMIXSQLHOSTS清空後,就可順利設定Server及Host Information了。
2016年7月2日 星期六
informix Routine (equal) can not be resolved
使用TSQL慣了,再來寫其他資料庫的SQL時都覺得好痛苦。
尤其是寫INFORMIX的STORED PROCEDURE,更是覺得自已的效率好低。
因為不習慣在VI下編輯(足以證明我年紀還沒老到那個TERMINAL MODE的年代...),所以通常都是用NOTEPAD++寫好,再貼到VI下執行dbaccess(其實是VI不太會用啦...)
今天寫了一個漏漏長的SP,執行後一直有個錯誤
informix Routine (equal) can not be resolved
搞啥啊,找了半天根本也沒有一個叫equal的函數,用debug file方式下trace,才發現原來有一段SQL做了二個欄位的比較,回傳boolean的型態,結果我用了數值0/1來判斷造成的錯誤。(應該要用 variablename = 'T' 或 variablename = 'F'來判斷)
這訊息也太不直覺了吧。
每次寫完一個SP,都有點昏的感覺。
尤其是寫INFORMIX的STORED PROCEDURE,更是覺得自已的效率好低。
因為不習慣在VI下編輯(足以證明我年紀還沒老到那個TERMINAL MODE的年代...),所以通常都是用NOTEPAD++寫好,再貼到VI下執行dbaccess(其實是VI不太會用啦...)
今天寫了一個漏漏長的SP,執行後一直有個錯誤
informix Routine (equal) can not be resolved
搞啥啊,找了半天根本也沒有一個叫equal的函數,用debug file方式下trace,才發現原來有一段SQL做了二個欄位的比較,回傳boolean的型態,結果我用了數值0/1來判斷造成的錯誤。(應該要用 variablename = 'T' 或 variablename = 'F'來判斷)
這訊息也太不直覺了吧。
每次寫完一個SP,都有點昏的感覺。
2014年9月30日 星期二
SQL Server Openquery Informix unicdoe db
在SQL SERVER 2008R2 10.50.2500 上建立一個LIKED SERVER連結INFORMIX,OPENQUERY時遇到了一個錯誤
testab中只有一個欄位coltest varchar(40),輸入一個UNICODE的字,查詢後出現錯誤
select * from openquery (ifx_v12,'select * from testab')
訊息 7339,層級 16,狀態 1,行 1 連結伺服器 'ifx_v12' 的 OLE DB 提供者 'MSDASQL' 傳回無效的資料給資料行 '[MSDASQL].coltest'。
若改用
execute(N'select * from bev') at ifx_v12
則可執行但回傳的字變成??了
Informix 12.10.FC3WE 64bit dynamic online , CLIENT_LOCALE、SERVER_LOCALE、DB_LOCALE皆為zh_TW.uft8
ODBC為 IBM INFOMRIX ODBC 4.10 FD3DE 64bit版本
測試改用OLE DB ,設好後有以下的錯誤。
An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)
Cannot initialize the data source object of OLE DB provider "Ifxoledbc" for linked server "ifx_v12". (Microsoft SQL Server, Error: 7303)
找了一些參考 http://www.sqlservercentral.com/Forums/Topic564076-17-1.aspx 也無法連結。
一直都是用ODBC設定LINKED SERVER,但之前的INFORMIX DB都是BIG5沒有問題,這次換成UNICODE版本後就無法正常使用OPENQUERY了。
testab中只有一個欄位coltest varchar(40),輸入一個UNICODE的字,查詢後出現錯誤
select * from openquery (ifx_v12,'select * from testab')
訊息 7339,層級 16,狀態 1,行 1 連結伺服器 'ifx_v12' 的 OLE DB 提供者 'MSDASQL' 傳回無效的資料給資料行 '[MSDASQL].coltest'。
若改用
execute(N'select * from bev') at ifx_v12
則可執行但回傳的字變成??了
Informix 12.10.FC3WE 64bit dynamic online , CLIENT_LOCALE、SERVER_LOCALE、DB_LOCALE皆為zh_TW.uft8
ODBC為 IBM INFOMRIX ODBC 4.10 FD3DE 64bit版本
測試改用OLE DB ,設好後有以下的錯誤。
An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)
Cannot initialize the data source object of OLE DB provider "Ifxoledbc" for linked server "ifx_v12". (Microsoft SQL Server, Error: 7303)
找了一些參考 http://www.sqlservercentral.com/Forums/Topic564076-17-1.aspx 也無法連結。
一直都是用ODBC設定LINKED SERVER,但之前的INFORMIX DB都是BIG5沒有問題,這次換成UNICODE版本後就無法正常使用OPENQUERY了。
參考幾篇討論,突然發現有人說SQL SERVER不支援UFT8??
再看了幾篇相關的討論文章,東拼西湊後,改回使用ODBC,最後算是找到解法了
1.先進入ODBC 64位元 設定,在Environment 頁籤下,Client Locale設為zh_TW.57372,Database Locale設為zh_TW.57372
2.在Advance頁籤中,勾選 Report Char columns as Wchar columns
3.在IBM Informix Client SDK 4.10 (64-bit)下開啟SetNet32 找到 GL_USEGLU將值設為1 (這個我在ODBC找不到可設定的地方,只能先在SetNet32 下設定)
4.重新啟動SQL SERVER (只要ODBC 參數或SetNet32 值有變動,最好都重啟一下SQL SERVER)
然後OPENQUERY中文字就正常啦,可以select 也可以insert。
再看了幾篇相關的討論文章,東拼西湊後,改回使用ODBC,最後算是找到解法了
1.先進入ODBC 64位元 設定,在Environment 頁籤下,Client Locale設為zh_TW.57372,Database Locale設為zh_TW.57372
2.在Advance頁籤中,勾選 Report Char columns as Wchar columns
3.在IBM Informix Client SDK 4.10 (64-bit)下開啟SetNet32 找到 GL_USEGLU將值設為1 (這個我在ODBC找不到可設定的地方,只能先在SetNet32 下設定)
4.重新啟動SQL SERVER (只要ODBC 參數或SetNet32 值有變動,最好都重啟一下SQL SERVER)
然後OPENQUERY中文字就正常啦,可以select 也可以insert。
2014年1月6日 星期一
informix GLS-cr
informix DB 版本 更新到IBM Informix Dynamic Server Version 11.50.FC9
無法查詢條件 like '許%'
因為許這個字的low byte 為\,造成系統誤判後頭字元為保留字,所以無法正確查詢。
更新DB後需再次安裝GLS以確保中文查詢正確。
無法查詢條件 like '許%'
因為許這個字的low byte 為\,造成系統誤判後頭字元為保留字,所以無法正確查詢。
更新DB後需再次安裝GLS以確保中文查詢正確。
2013年8月28日 星期三
SQL SERVER LEAP YEAR(轉)
只適用在SQL SERVER 2012 參考
SELECT (IIF(DATEPART(dd,(EOMONTH(CONCAT(1910,'0201')))) = 29,1,0))
其他版本SQL SERVER 參考
再加一個INFORMIX datediff
informix datediff
CREATE FUNCTION datediff
(in_type varchar(5),in_sdate integer, in_edate integer )
RETURNING integer ;
DEFINE p_sdate date;
DEFINE p_edate date;
DEFINE p_day integer;
--如果國曆日期有誤,一律傳回NULL
BEGIN
ON EXCEPTION
LET p_day = null::integer;
END EXCEPTION
--判別是否為民國前
IF in_sdate < 0 THEN
LET in_sdate = ABS(in_sdate)+19110000- ROUND(ABS(in_sdate/10000))*20000;
ELSE
LET in_sdate = in_sdate + 19110000;
END IF ;
IF in_edate < 0 THEN
LET in_edate = ABS(in_edate)+19110000- ROUND(ABS(in_edate/10000))*20000;
ELSE
LET in_edate = in_edate + 19110000;
END IF ;
--轉為西元日期
SELECT (TO_DATE((in_edate)::char(8),'%Y%m%d'))
, (TO_DATE((in_sdate)::char(8),'%Y%m%d'))
INTO p_edate,p_sdate
FROM empty;
IF UPPER(in_type) IN ('DAY','D') THEN
LET p_day = p_edate - p_sdate;
ELSE IF UPPER(in_type) IN ('MONTH','M') THEN
LET p_day = ((YEAR(p_edate) - YEAR(p_sdate)) * 12) +
(MONTH(p_edate) - MONTH(p_sdate));
ELSE IF UPPER(in_type) IN ('YEAR','Y') THEN
LET p_day = YEAR(p_edate) - YEAR(p_sdate) ;
END IF; END IF; END IF;
END;
RETURN p_day;
END FUNCTION;
(in_type varchar(5),in_sdate integer, in_edate integer )
RETURNING integer ;
DEFINE p_sdate date;
DEFINE p_edate date;
DEFINE p_day integer;
--如果國曆日期有誤,一律傳回NULL
BEGIN
ON EXCEPTION
LET p_day = null::integer;
END EXCEPTION
--判別是否為民國前
IF in_sdate < 0 THEN
LET in_sdate = ABS(in_sdate)+19110000- ROUND(ABS(in_sdate/10000))*20000;
ELSE
LET in_sdate = in_sdate + 19110000;
END IF ;
IF in_edate < 0 THEN
LET in_edate = ABS(in_edate)+19110000- ROUND(ABS(in_edate/10000))*20000;
ELSE
LET in_edate = in_edate + 19110000;
END IF ;
--轉為西元日期
SELECT (TO_DATE((in_edate)::char(8),'%Y%m%d'))
, (TO_DATE((in_sdate)::char(8),'%Y%m%d'))
INTO p_edate,p_sdate
FROM empty;
IF UPPER(in_type) IN ('DAY','D') THEN
LET p_day = p_edate - p_sdate;
ELSE IF UPPER(in_type) IN ('MONTH','M') THEN
LET p_day = ((YEAR(p_edate) - YEAR(p_sdate)) * 12) +
(MONTH(p_edate) - MONTH(p_sdate));
ELSE IF UPPER(in_type) IN ('YEAR','Y') THEN
LET p_day = YEAR(p_edate) - YEAR(p_sdate) ;
END IF; END IF; END IF;
END;
RETURN p_day;
END FUNCTION;
2013年2月21日 星期四
腦力退化....null 值比較
今天在informix 做一個簡單的查詢時竟然對這個查詢結果懷疑了起來
create table test(col1 char(1) not null, col2 char(1));
insert into test values ('1' ,null);
insert into test values ('1' ,'1');
select * from test where col2 <> '1' ;
原本以為會回傳第一筆資料. 但卻回傳0筆.
以為是informix才會這樣,結果到sql server也是如此.
我的頭腦真是老化了,怎麼懷疑起這樣的結果呢.
null 與任何值比較應都是無法比的.
欄位值有null先轉型再比較唄
--tsql
select * from test where coalesce(col2,'') <> '1' ;
--informix
select * from test where nvl(col2,'') <> '1' ;
參考NULL 值說明
create table test(col1 char(1) not null, col2 char(1));
insert into test values ('1' ,null);
insert into test values ('1' ,'1');
select * from test where col2 <> '1' ;
原本以為會回傳第一筆資料. 但卻回傳0筆.
以為是informix才會這樣,結果到sql server也是如此.
我的頭腦真是老化了,怎麼懷疑起這樣的結果呢.
null 與任何值比較應都是無法比的.
欄位值有null先轉型再比較唄
--tsql
select * from test where coalesce(col2,'') <> '1' ;
--informix
select * from test where nvl(col2,'') <> '1' ;
參考NULL 值說明
2013年1月22日 星期二
Could not update a row in the table.
利用datatable讀取及異動資料.
結果exception message為
ERROR [HY000] [Informix][Informix ODBC Driver][Informix]Could not update a row in the table.
錯在哪一筆也看不出來?
是資料被lock?
查了半天毫無頭緒.
最後只好一筆一筆loop逐筆檢查看是哪一筆寫不進去
結果這個錯誤緣自於unique index duplicate 造成的.
昏+暈....................................
結果exception message為
ERROR [HY000] [Informix][Informix ODBC Driver][Informix]Could not update a row in the table.
錯在哪一筆也看不出來?
是資料被lock?
查了半天毫無頭緒.
最後只好一筆一筆loop逐筆檢查看是哪一筆寫不進去
結果這個錯誤緣自於unique index duplicate 造成的.
昏+暈....................................
2012年11月10日 星期六
informix 11.5 charindex
informix 11.5(含)版本以前沒有提供charindex功能.
因為想要依傳入的尋找 字元組合來取得符合的position,所以為了方便,自已寫了一個湊合著用
以下function是區分大小寫尋找的..
--DOP FUNCTION uf_charindex;
/*
in_str:被搜尋的字元
in_delimiter;尋找字元
in_occurence:被找到的次數
in_exact:是否依in_delimiter逐字尋找
*/
CREATE FUNCTION uf_charindex
(in_str VARCHAR(255),in_delimiter VARCHAR(255)
,in_occurence INTEGER, in_exact CHAR(1) )
RETURNING INTEGER ;
DEFINE q_pos INTEGER;
DEFINE i INTEGER;
DEFINE q_len INTEGER;
DEFINE q_time INTEGER;
DEFINE j INTEGER;
DEFINE q_len_del INTEGER;
DEFINE q_found CHAR(1);
DEFINE q_str VARCHAR(255);
DEFINE q_step INTEGER;
IF nvl(in_occurence,1) <=1 THEN
LET in_occurence = 1;
END IF;
LET q_time=0;
LET i = 1;
LET q_pos = 0;
LET j = 1;
LET q_found = '0';
LET q_step = 1;
LET q_len = char_length(in_str);
LET q_len_del = char_length(in_delimiter);
--是否依in_delimiter逐字尋找符合字
IF in_exact = '1' THEN --完全符合
LET q_step = q_len_del;--先記下完整字長度
LET q_len_del = 1; --最外層只跑一次即可
END IF ;
FOR j = 1 TO q_len_del STEP 1
LET i = 1;
LET q_time = 0;
LET q_pos = 0;
LET q_found = '0';
--取比較字(若in_exact='1'則全部符合)
IF in_exact = '1' THEN
LET q_str = in_delimiter;
ELSE --否則逐字找直到找到in_occurence為止
LET q_str = substr(in_delimiter,j,1);
END IF;
FOR i = 1 TO q_len STEP 1
IF substr(in_str,i,q_step) = q_str THEN
LET q_pos = i;
LET q_time = q_time +1;
--找到後若與指定出現次數相符則結束
IF q_time = in_occurence THEN
LET q_found = '1';
EXIT FOR;
END IF;
END IF;
END FOR;
IF q_found = '1' THEN
EXIT FOR;
END iF;
END FOR;
RETURN q_pos;
END FUNCTION;
測試一下
SELECT FIRST 1 uf_charindex("臺東縣臺東市","縣市",1,'0') FROM systables;
傳回3
SELECT FIRST 1 uf_charindex("臺北市信義區","縣市",1,'0') FROM systables;
傳回3
SELECT FIRST 1 uf_charindex("臺東縣臺東市","市縣",1,'0') FROM systables;
傳回6
SELECT FIRST 1 uf_charindex("This is a book","book",1,'1') FROM systables;
傳回11
SELECT FIRST 1 uf_charindex("This are a lot of bOOks","O",2,'1') FROM systables;
傳回21
因為想要依傳入的尋找 字元組合來取得符合的position,所以為了方便,自已寫了一個湊合著用
以下function是區分大小寫尋找的..
--DOP FUNCTION uf_charindex;
/*
in_str:被搜尋的字元
in_delimiter;尋找字元
in_occurence:被找到的次數
in_exact:是否依in_delimiter逐字尋找
*/
CREATE FUNCTION uf_charindex
(in_str VARCHAR(255),in_delimiter VARCHAR(255)
,in_occurence INTEGER, in_exact CHAR(1) )
RETURNING INTEGER ;
DEFINE q_pos INTEGER;
DEFINE i INTEGER;
DEFINE q_len INTEGER;
DEFINE q_time INTEGER;
DEFINE j INTEGER;
DEFINE q_len_del INTEGER;
DEFINE q_found CHAR(1);
DEFINE q_str VARCHAR(255);
DEFINE q_step INTEGER;
IF nvl(in_occurence,1) <=1 THEN
LET in_occurence = 1;
END IF;
LET q_time=0;
LET i = 1;
LET q_pos = 0;
LET j = 1;
LET q_found = '0';
LET q_step = 1;
LET q_len = char_length(in_str);
LET q_len_del = char_length(in_delimiter);
--是否依in_delimiter逐字尋找符合字
IF in_exact = '1' THEN --完全符合
LET q_step = q_len_del;--先記下完整字長度
LET q_len_del = 1; --最外層只跑一次即可
END IF ;
FOR j = 1 TO q_len_del STEP 1
LET i = 1;
LET q_time = 0;
LET q_pos = 0;
LET q_found = '0';
--取比較字(若in_exact='1'則全部符合)
IF in_exact = '1' THEN
LET q_str = in_delimiter;
ELSE --否則逐字找直到找到in_occurence為止
LET q_str = substr(in_delimiter,j,1);
END IF;
FOR i = 1 TO q_len STEP 1
IF substr(in_str,i,q_step) = q_str THEN
LET q_pos = i;
LET q_time = q_time +1;
--找到後若與指定出現次數相符則結束
IF q_time = in_occurence THEN
LET q_found = '1';
EXIT FOR;
END IF;
END IF;
END FOR;
IF q_found = '1' THEN
EXIT FOR;
END iF;
END FOR;
RETURN q_pos;
END FUNCTION;
測試一下
SELECT FIRST 1 uf_charindex("臺東縣臺東市","縣市",1,'0') FROM systables;
傳回3
SELECT FIRST 1 uf_charindex("臺北市信義區","縣市",1,'0') FROM systables;
傳回3
SELECT FIRST 1 uf_charindex("臺東縣臺東市","市縣",1,'0') FROM systables;
傳回6
SELECT FIRST 1 uf_charindex("This is a book","book",1,'1') FROM systables;
傳回11
SELECT FIRST 1 uf_charindex("This are a lot of bOOks","O",2,'1') FROM systables;
傳回21
2012年10月31日 星期三
informix dateadd
informix 11.5模擬sql server dateadd, 但傳入及傳出皆為國曆日期數字
CREATE FUNCTION ifx_f_dateadd
(in_type varchar(5),in_date integer, in_diff integer )
RETURNING integer ;
DEFINE p_date date;
DEFINE p_day integer;
--轉為西元日期
--改成以下方式來轉換
--因為上述方式會隨著DB版本或onconfig中日期格式指定而變,可能會有錯誤.
SELECT (TO_DATE((in_date+19110000)::char(8),'%Y%m%d'))
INTO p_date FROM empty;
IF UPPER(in_type) IN ('DAY','D') THEN
SELECT p_date + in_diff into p_date from empty;
ELSE IF UPPER(in_type) in ('MONTH','M') THEN
--改成以下方式,因為1011031 取下月時會有The result of a datetime computation is out of range.的錯誤,
--以下方法閏年也適用
SELECT add_months(p_date,in_diff ) into p_date from empty;
ELSE IF UPPER(in_type) IN ('YEAR','Y' ) THEN
--以下方法閏年也適用
SELECT add_months(p_date,in_diff*12) into p_date from empty;
END IF; END IF; END IF; --這一串END IF; 搞了我一個小時才知道要這樣寫....
SELECT TO_CHAR(p_date ,'%Y%m%d')::INTEGER - 19110000
INTO p_day
FROM empty;
END FUNCTION;
測試,
CREATE TABLE empty (col1 INT);
INSERT into empty VALUES(0);
INSERT into empty VALUES(0);
select ifx_f_dateadd('y',1010814,-1) FROM empty;
回傳1000814
select sr_f_dateadd('m',1011031,1) FROM empty
回傳1011130
select sr_f_dateadd('y',1010229,-1) FROM empty
回傳1000228
ps.2012/08/14寫第一版,3個月後,知識長進,大改一番.
2012年10月23日 星期二
Informix catalogs 讀取資料表及欄位資訊
--資料表
SELECT * FROM systables WHERE tabid > 99
;
--資料表及欄位
SELECT * FROM systables a INNER JOIN syscolumns b
ON a.tabid = b.tabid
WHERE a.tabid > 99
;
--資料表欄位及類型 (參考此dbform此篇討論 )
SELECT t.tabname,c.colno, c.colname[1,20] column,
CASE coltype
WHEN 0 THEN 'char(' || TRIM(CAST (c.collength AS CHAR(5))) || ')'
WHEN 1 THEN 'smallint'
WHEN 2 THEN 'integer'
WHEN 3 THEN 'float'
WHEN 4 THEN 'smallfloat'
WHEN 5 THEN 'decimal(' ||
TRIM(CAST(TRUNC(c.collength/256) AS VARCHAR(8)) || ',' ||
CAST(c.collength - TRUNC(c.collength/256)*256 AS VARCHAR(8))) || ')'
WHEN 6 THEN 'serial'
WHEN 7 THEN 'date'
WHEN 8 THEN 'money(' ||
TRIM(CAST(TRUNC(c.collength/256) AS VARCHAR(8)) || ',' ||
CAST(c.collength - TRUNC(c.collength/256)*256 AS VARCHAR(8))) || ')'
WHEN 9 THEN 'null'
WHEN 10 THEN 'datetime'
WHEN 11 THEN 'byte'
WHEN 12 THEN 'text'
WHEN 13 THEN 'varchar(' || TRIM(CAST(c.collength AS CHAR(5))) || ')'
WHEN 14 THEN 'interval'
WHEN 15 THEN 'nchar(' || TRIM(CAST(c.collength AS CHAR(5))) || ')'
WHEN 16 THEN 'nvarchar(' || TRIM(CAST(c.collength AS CHAR(5))) || ')'
WHEN 17 THEN 'int8'
WHEN 18 THEN 'serial8'
WHEN 19 THEN 'set'
WHEN 20 THEN 'multiset'
WHEN 21 THEN 'list'
WHEN 22 THEN 'row'
WHEN 23 THEN 'collection'
WHEN 24 THEN 'rowdef'
WHEN 40 THEN 'lvarchar'
WHEN 256 THEN 'char(' || TRIM(CAST(c.collength AS CHAR(5))) ||
') not null'
WHEN 257 THEN 'smallint not null'
WHEN 258 THEN 'integer not null'
WHEN 259 THEN 'float not null'
WHEN 260 THEN 'smallfloat not null'
WHEN 261 THEN 'decimal('||
TRIM(CAST(TRUNC(c.collength/256) AS VARCHAR(8)) || ',' ||
CAST(c.collength - TRUNC(c.collength/256)*256 AS VARCHAR(8))) ||
') not null'
WHEN 262 THEN 'serial not null'
WHEN 263 THEN 'date not null'
WHEN 264 THEN 'money(' ||
TRIM(CAST(TRUNC(c.collength/256) AS VARCHAR(8)) || ',' ||
CAST(c.collength - TRUNC(c.collength/256)*256 AS VARCHAR(8))) ||
') not null'
WHEN 265 THEN 'null not null'
WHEN 266 THEN 'datetime not null'
WHEN 267 THEN 'byte not null'
WHEN 268 THEN 'text not null'
WHEN 269 THEN 'varchar(' || TRIM(CAST(c.collength AS CHAR(5))) ||
') not null'
WHEN 270 THEN 'interval not null'
WHEN 271 THEN 'nchar(' || TRIM(CAST(c.collength AS CHAR(5))) ||
') not null'
WHEN 272 THEN 'nvarchar(' || TRIM(CAST(c.collength AS CHAR(5))) ||
') not null'
WHEN 273 THEN 'int8 not null'
WHEN 274 THEN 'serial8 not null'
WHEN 275 THEN 'set not null'
WHEN 276 THEN 'multiset not null'
WHEN 277 THEN 'list not null'
WHEN 278 THEN 'row not null'
WHEN 279 THEN 'collection not null'
WHEN 280 THEN 'rowdef not null'
ELSE CAST(coltype AS CHAR(10))
END datatype
FROM systables t INNER JOIN syscolumns c
ON t.tabid = c.tabid
WHERE t.tabid > 99
ORDER BY 1,2
;
2012年9月18日 星期二
Informix 重設Serial 欄位值
在SQL Server 是下 DBCC CHECKIDENT (youTableName, reseed, 1);
在Informix 找到幾種方法可以做
1.drop table and recreate (廢話)
2.insert into yourTable(SerialCol) values(2147483647);
truncate table yourTable;
3.alter table yourTable modify(SerialCol integer);
truncate table yourTable;
alter table yourTable modify(SerialCol serial);
在Informix 找到幾種方法可以做
1.drop table and recreate (廢話)
2.insert into yourTable(SerialCol) values(2147483647);
truncate table yourTable;
3.alter table yourTable modify(SerialCol integer);
truncate table yourTable;
alter table yourTable modify(SerialCol serial);
2012年9月14日 星期五
informix DBINFO function
--取得主機名稱
SELECT FIRST 1 DBINFO('dbhostname') FROM systables;
--取得informix db 版本 (IBM Informix Dynamic Server Version 11.50.UC7)
SELECT FIRST 1 DBINFO('version','full') FROM systables;
---取得時間, 很特別的是, 前者會取得目前真正的時日
--但CURRENT在同一個stored procedure中,不論使用幾次,都是一樣的
--所以為了log方便,應採用前者
SELECT DBINFO('utc_to_datetime', sh_curtime) , CURRENT FROM sysmaster:sysshmvals;
--取得Serial 欄位流水號,必需緊接在insert into sql後使用
insert into table values (1,2,3);
SELECT FIRST 1 DBINFO('sqlca.sqlerrd1') from systables;
--取得呼叫此方法前最後sql的影響筆數
SELECT FIRST 1 DBINFO('sqlca.sqlerrd2') from systables ;
SELECT FIRST 1 DBINFO('dbhostname') FROM systables;
--取得informix db 版本 (IBM Informix Dynamic Server Version 11.50.UC7)
SELECT FIRST 1 DBINFO('version','full') FROM systables;
---取得時間, 很特別的是, 前者會取得目前真正的時日
--但CURRENT在同一個stored procedure中,不論使用幾次,都是一樣的
--所以為了log方便,應採用前者
SELECT DBINFO('utc_to_datetime', sh_curtime) , CURRENT FROM sysmaster:sysshmvals;
--取得Serial 欄位流水號,必需緊接在insert into sql後使用
insert into table values (1,2,3);
SELECT FIRST 1 DBINFO('sqlca.sqlerrd1') from systables;
--取得呼叫此方法前最後sql的影響筆數
SELECT FIRST 1 DBINFO('sqlca.sqlerrd2') from systables ;
2012年9月13日 星期四
informix 序號欄位取值
.net 中,如何取得informix table 新增後serial column 的流水號,然後再傳給另一個table進行使用
--建立測試表
create table bevtest
( col1 serial,
col2 varchar(50)
);
begin work;
insert into bevtest values(0,'test');
--此行需緊接著insert into table 後執行
select dbinfo('sqlca.sqlerrd1') as sn from empty into temp tmpsn with no log;
insert into bevtest select 0,sn||' this is sn" from tmpsn;
drop table tmpsn;
commit work;
--建立測試表
create table bevtest
( col1 serial,
col2 varchar(50)
);
begin work;
insert into bevtest values(0,'test');
--此行需緊接著insert into table 後執行
select dbinfo('sqlca.sqlerrd1') as sn from empty into temp tmpsn with no log;
insert into bevtest select 0,sn||' this is sn" from tmpsn;
drop table tmpsn;
commit work;
2012年9月11日 星期二
informix 時間 to_char
日期加時間格式
SELECT FIRST 1
TO_CHAR(CURRENT , '%Y/%m/%d %R:%S')
,TO_CHAR(CURRENT , '%Y/%m/%d %I:%M:%S %p')
FROM systables
回傳
2012/09/12 14:06:14 2012/09/12 02:06:14 下午
2012/09/27:
今天把寫好的SP拿到客戶的環境上執行
結果有個FUNCTION一直 出現 Invalid era, could not assign era date
怪怪,公司跑得好好的說.
查了半天之前用舊方法將國曆數字轉成西元日期,遇到客戶的環境沒有指定DBDATE格式,造成以下的寫法一直有問題
DEFINE p_date date
SELECT (((substr((in_date+19110000)::char(8),1,4))||'-'||
(substr((in_date+19110000)::char(8),5,2))||'-'||
(substr((in_date+19110000)::char(8),7,2)))::date)
INTO p_date FROM empty;
改成以下寫法就OK
SELECT (TO_DATE((in_date+19110000)::char(8),'%Y%m%d'))
INTO p_date FROM empty;
原來一直搞不懂為什麼INFORMIX中,有today 和current 二個方法
直到今天才知道, today的格式是跟隨著DBDATE的設定回傳日期及時間, current則是回傳固定格式的日期及時間
以下是客戶環境, DBDATE沒指定,所以預設應跟著DB_LOCALE=zh_TW.big5
以下是公司環境, DBDATE=Y4MD-
SELECT FIRST 1
TO_CHAR(CURRENT , '%Y/%m/%d %R:%S')
,TO_CHAR(CURRENT , '%Y/%m/%d %I:%M:%S %p')
FROM systables
回傳
2012/09/12 14:06:14 2012/09/12 02:06:14 下午
2012/09/27:
今天把寫好的SP拿到客戶的環境上執行
結果有個FUNCTION一直 出現 Invalid era, could not assign era date
怪怪,公司跑得好好的說.
查了半天之前用舊方法將國曆數字轉成西元日期,遇到客戶的環境沒有指定DBDATE格式,造成以下的寫法一直有問題
DEFINE p_date date
SELECT (((substr((in_date+19110000)::char(8),1,4))||'-'||
(substr((in_date+19110000)::char(8),5,2))||'-'||
(substr((in_date+19110000)::char(8),7,2)))::date)
INTO p_date FROM empty;
改成以下寫法就OK
SELECT (TO_DATE((in_date+19110000)::char(8),'%Y%m%d'))
INTO p_date FROM empty;
原來一直搞不懂為什麼INFORMIX中,有today 和current 二個方法
直到今天才知道, today的格式是跟隨著DBDATE的設定回傳日期及時間, current則是回傳固定格式的日期及時間
以下是客戶環境, DBDATE沒指定,所以預設應跟著DB_LOCALE=zh_TW.big5
| today | current |
| 中華民國101年10月3日 星期三 | 2012-10-03 16:55:28.00 |
以下是公司環境, DBDATE=Y4MD-
| today | current |
| 2012/10/03 | 2012-10-03 16:55:28.00 |
2012年8月11日 星期六
informix sql new line 換行
在SQL SERVER SQL 中換行為
1
2
在INFORMIX SQL中換行則需先執行換行設定後
以上只在當次session中生效.否則就要在$ONCONFIG 中將ALLOW_NEWLINE設定為1
參考來源 http://www.iiug.org/forums/classics/index.cgi/read/4100
後記:
後來建了一個function,在里頭進行折行效果,結果一直無法建立, 出現以下錯誤
查看informix online help說明,
Quotes on different lines:
測了半天,原來要在create function前先啟用 IFX_ALLOW_NEWLINE, 如下
SELECT '1' + char(13)+char(10) + '2'
結果為1
2
在INFORMIX SQL中換行則需先執行換行設定後
EXECUTE PROCEDURE IFX_ALLOW_NEWLINE('t');
再進行換行
select '1' ||'
'||'2' from empty ;以上只在當次session中生效.否則就要在$ONCONFIG 中將ALLOW_NEWLINE設定為1
參考來源 http://www.iiug.org/forums/classics/index.cgi/read/4100
後記:
後來建了一個function,在里頭進行折行效果,結果一直無法建立, 出現以下錯誤
-282 Found a quote for which there is no matching quote
查看informix online help說明,
Quotes on different lines:
- Run EXECUTE PROCEDURE ifx_allow_newline ('t'). This stays in effect until the end of your session.
- Set the ALLOW_NEWLINE parameter to 1 in the ONCONFIG configuration file and restart the database server.
測了半天,原來要在create function前先啟用 IFX_ALLOW_NEWLINE, 如下
EXECUTE PROCEDURE IFX_ALLOW_NEWLINE('t');
create function fn_bevtest
(i_col1 integer) RETURNING varchar(255);
define v_name varchar(255);
EXECUTE PROCEDURE IFX_ALLOW_NEWLINE('t');
select '1'||'
'||'2' into v_name from empty;
return v_name;
end function;
(i_col1 integer) RETURNING varchar(255);
define v_name varchar(255);
EXECUTE PROCEDURE IFX_ALLOW_NEWLINE('t');
select '1'||'
'||'2' into v_name from empty;
return v_name;
end function;
2012年8月4日 星期六
informix 更改IP
將hyper-v 的vhd移到windows 7環境利用virtual box掛載起來後,
因為家里的區域網路是192.168.1.*, 試了一個晚上,家里的router一直無法成功將LAN IP改設成192.168.0.*的網段.
所以只好更改redhat的主機IP.
改了IP後, informix上的IP也要跟著變更.
修改 INFORMIXDIR/etc/sqlhosts 的設定如下紅字
testalias onipcshm 192.168.1.125 sqlexec
test onsoctcp 192.168.1.125 9999
另外,在INFORMIX ODBC設定時,由於同一個server設定對應到不同IP會有互蓋的問題
故可將另一個IP的,改用另一個informix 別名來設定.
這樣就可以在使用新舊DB皆有相同server name時,做不同的測試了
設定完畢重啟動Informix Server
因為家里的區域網路是192.168.1.*, 試了一個晚上,家里的router一直無法成功將LAN IP改設成192.168.0.*的網段.
所以只好更改redhat的主機IP.
改了IP後, informix上的IP也要跟著變更.
修改 INFORMIXDIR/etc/sqlhosts 的設定如下紅字
testalias onipcshm 192.168.1.125 sqlexec
test onsoctcp 192.168.1.125 9999
另外,在INFORMIX ODBC設定時,由於同一個server設定對應到不同IP會有互蓋的問題
故可將另一個IP的,改用另一個informix 別名來設定.
這樣就可以在使用新舊DB皆有相同server name時,做不同的測試了
設定完畢重啟動Informix Server
onmode -ky
oninit
2012年7月24日 星期二
Win7 64 bit Informix ODBC測試
在windows 7 64bit 安裝informix ODBC(我是安裝IBM Informix Client-SDK3.50.xC7版 32bit及64bit),幾個重點
1.配合主機DB版本若為32bit,則仍需在win7 64bit環境下安裝 32bit informix connect ,最新版本可到此網址下載
2.若想利用sql server 2008 R2 建立linked db, 因為R2是64 bit,所以win7也必需要安裝64bit informix connect .
3.自已測試了一下, 想要使用 sql server 2008 R2的Import Data 匯入資料, 這時,他又只認32 bit ODBC的設定???
4.再測試了一下, 使用sql server 2008 R2 SSIS 連結ODBC, 也是只認32 bit ODBC的設定??
5.在SSIS data flow中, 建立informix 轉換到sql server 的處理, 結果仍是一樣的超級無敵難用. 透過ADO NET Source轉換時,仍強迫你要做 unicode and non-unicode的轉換.
為什麼不能依照informix 資料庫欄位的定義來做轉換呢??
為什麼不能和sql 2000 DTS 的用法一樣呢??還我原來的odbc provider啊,我不要ADO NET Source...
為什麼我要浪費時間做型別轉換呢??
為什麼經過了2005,2008,2008R2這個鳥問題仍然存在呢??
6.安裝完ODBC後,更改Enviornment 頁籤下的isolation level 為1-Read Uncommitted後, 測試連結,出現
Test connection was NOT successful.[Informix][Informix ODBC Driver][Informix]Transaction not available.
記得先檢查informix db的log mode是否為buffer log.否則無法設定isolation mode
2012年5月10日 星期四
informix onlog
想要查看某段時間內某使用者的DB記錄. 借助onlog的查看,可略知一二.
首先先查看informix 下的onlog.log檔,找出相對應時間內的log number有哪些
然後執行以下指令
onlog -l -n 470552 -u myuser | more
-n log number
-u 指定使用者
-l 顯示完整log訊息
首先先查看informix 下的onlog.log檔,找出相對應時間內的log number有哪些
然後執行以下指令
onlog -l -n 470552 -u myuser | more
-n log number
-u 指定使用者
-l 顯示完整log訊息
更多參數說明如下
Usage: onlog [-l] [-q] [-b] [-d <tape device>] [-n <log unique identifier>]
[-u <user name>] [-t <TBLspace number>] [-x <transaction number>]
-l Display maximum information about each log record
-q Do not display program header
-b Display information about logged BLOB pages (-d option only)
-d Read from tape device
-n Display the specified log(s)
-u Display the specified user(s)
-t Display the specified TBLspace(s)
-x Display the specified transaction(s)
Usage: onlog [-l] [-q] [-b] [-d <tape device>] [-n <log unique identifier>]
[-u <user name>] [-t <TBLspace number>] [-x <transaction number>]
-l Display maximum information about each log record
-q Do not display program header
-b Display information about logged BLOB pages (-d option only)
-d Read from tape device
-n Display the specified log(s)
-u Display the specified user(s)
-t Display the specified TBLspace(s)
-x Display the specified transaction(s)
訂閱:
文章 (Atom)
IIS 網站無法下載中文檔名檔案因為取消高位元字元
網址+中文檔案名稱方式下載檔案顯示 404 - 找不到檔案或目錄。 但英數字檔案名稱則可下載。 因為設定GCB IIS,其中1項 將高位元字元預設取消勾選了。 27 TWGCB-04-014-0028 要求篩選與其他限制模組 允許高位元字元 這項原則設定決定查詢...
-
一個老舊的aspx web form專案,調了一些功能建置成功,但進行部署時顯示以下錯誤。 在應用程式層級之外使用註冊為 allowDefinition='MachineToApplication' 的區段發生錯誤。錯誤的原因可能是虛擬目錄尚未在 IIS 中設定為...
-
Row.Cells[2].Text == "abc" ? "ok" : "not ok" ; 或加入Microsoft. VisualBasic 參考使用 vb namespace using Microsoft...
-
freeFTPd是套免費的SFTP SERVER支援22 port SFTP及21port FTP,一般找到免費的都不支援SFTP只有技援FTPS。 之前一直有個困擾在幾台主機安裝後,有幾台重開機後,SFTP SERVER必須手動去啟動,一直以來老是搞不懂為什麼,今天看到一篇文...