亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 6013 | 回復(fù): 6
打印 上一主題 下一主題

[問題求助] DB2自定義TRIM函數(shù) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2010-10-27 13:24 |只看該作者 |倒序瀏覽
最近因項目的需要,須在DB2中自建一個自定義的TRIM函數(shù),功能是去掉字符串前后的空字符,如空格,TAB之類的東西.

版上有許多這方面的討論以及代碼,我COPY了Jamesqiao所寫的用來測試:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <sys/stat.h>
  5. #include <sys/types.h>
  6. #include <sqludf.h>


  7. //Macro for iendity the blanks
  8. #define isSpaces(ch) (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\b' || ch == '\f' || ch == '\n')

  9. char *TrimChr(char *pszSource)
  10. {
  11.         //pointer of the first char of string
  12.         char *pszHead = pszSource;
  13.         //pointer of the last non-blank char
  14.         char *pszLast = &pszSource[strlen(pszSource)-1];
  15.         //search the location of the last non-blank char
  16.         while (isSpaces(*pszLast))
  17.                 --pszLast;
  18.         *(++pszLast) = '\0';
  19.         //search the first non-blank char for left shift the string
  20.         for ( ; (*pszHead != '\0') && (pszHead != pszLast); ++pszHead)
  21.         {
  22.                 if (! isSpaces(*pszHead))
  23.                 {
  24.                         strcpy(pszSource, pszHead);
  25.                         break;
  26.                 }
  27.         }

  28.         return pszSource;
  29. }

  30. int main(int argc,char *argv[])
  31. {
  32.         printf("\"");
  33.         printf(argv[1]);
  34.         printf("\"\n");
  35.         printf("\"");
  36.         printf(TrimChr(argv[1]));
  37.         printf("\"\n");
  38. }
復(fù)制代碼
代碼可以編譯成功并在LINUX環(huán)境下運行的.


但是我想用它變成DB2的一個自定義函數(shù)時,老是出問題:
  1. values TrimChr('   aaaa    ');

  2. [IBM][CLI Driver][DB2/LINUX] SQL0444N  Routine "TRIMCHR" (specific name "SQL080529112348600") is implemented with code in library or path ".../sqllib/function/TrimChr", function "TrimChr" which cannot be accessed.  Reason code: "5".  SQLSTATE=42724
復(fù)制代碼
自定義函數(shù)是如此寫的:
  1. CREATE FUNCTION TrimChr (VARCHAR(400))
  2.                            RETURNS VARCHAR(400)   
  3.                            EXTERNAL NAME '/home/db2inst1/sqllib/function/TrimChr!TrimChr'
  4.                            LANGUAGE C  
  5.                            NULL CALL  
  6.                            PARAMETER STYLE DB2SQL  
  7.                            NO SQL  
  8.                            DETERMINISTIC  
  9.                            NO EXTERNAL ACTION
  10.                            NOT FENCED;

  11. GRANT EXECUTE ON FUNCTION TRIMCHR(VARCHAR(400)) TO PUBLIC;
復(fù)制代碼
請問是什么原因?是編譯的問題?還是C函數(shù)的問題(與指針有關(guān)?)?

論壇徽章:
0
2 [報告]
發(fā)表于 2010-10-27 14:04 |只看該作者
Reason code 5 :
There was insufficient memory to load the library containing
The function or one or more symbols could not be resolved.
Contact the routine creator or your database administrator to
Make sure that the library was correctly linked. All required
Libraries to resolve referenced symbols such as external
Functions must be available. If a lack of memory is determined
Then the system configuration may need to be changed to make more
Memory available to DB2.

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
3 [報告]
發(fā)表于 2010-10-27 14:25 |只看該作者
專業(yè)人士面對陌生領(lǐng)域一般都是先從 hello world 開始吧。
這個喚作“單元測試”

論壇徽章:
0
4 [報告]
發(fā)表于 2010-10-27 18:16 |只看該作者
我查了一下網(wǎng)上的資料,發(fā)現(xiàn)人家是這樣寫的:
  1. #include <pcre.h>
  2. #include <sqludf.h>

  3. void regexpSimple(
  4.     // input parameters
  5.     SQLUDF_VARCHAR *pattern,      SQLUDF_CLOB *str,
  6.     // output
  7.     SQLUDF_INTEGER *match,
  8.     // null indicators
  9.     SQLUDF_NULLIND *pattern_ind,  SQLUDF_NULLIND *str_ind,
  10.     SQLUDF_NULLIND *match_ind,
  11.     SQLUDF_TRAIL_ARGS)
  12. {
  13.     pcre *re = NULL;
  14.     const char *error = NULL;
  15.     int errOffset = 0;
  16.     int rc = 0;

  17.     // we assume successful return
  18.     *match_ind = 0;

  19.     // compile the pattern to its internal representation
  20.     re = pcre_compile(pattern, 0 /* default options */, &error,
  21.         &errOffset, NULL);
  22.     if (re == NULL) {
  23.         snprintf(SQLUDF_MSGTX, 70, "Regexp compilation failed at "
  24.             "offset %d: %s\n", errOffset, error);
  25.         strcpy(SQLUDF_STATE, "38900");
  26.         (*pcre_free)(re);
  27.         return;
  28.     }

  29.     // match the string againts the pattern
  30.     rc = pcre_exec(re, NULL, str->data, str->length, 0,
  31.             0 /* default options */, NULL, 0);
  32.     switch (rc) {
  33.       case PCRE_ERROR_NOMATCH:
  34.         *match = 0;
  35.         break;
  36.       case PCRE_ERROR_BADOPTION:
  37.         snprintf(SQLUDF_MSGTX, 70, "An unrecognized bit was set in the "
  38.             "options argument");
  39.         strcpy(SQLUDF_STATE, "38901");
  40.         break;
  41.       case PCRE_ERROR_NOMEMORY:
  42.         snprintf(SQLUDF_MSGTX, 70, "Not enough memory available.");
  43.         strcpy(SQLUDF_STATE, "38902");
  44.         break;
  45.       default:
  46.         if (rc < 0) {
  47.             snprintf(SQLUDF_MSGTX, 70, "A regexp match error "
  48.                 "occured: %d", rc);
  49.             strcpy(SQLUDF_STATE, "38903");
  50.         }
  51.         else {
  52.             *match = 1;
  53.         }
  54.         break;
  55.     }

  56.     // cleanup
  57.     (*pcre_free)(re);
  58.     return;
  59. }
復(fù)制代碼
輸入與輸出都是放在參數(shù)里,返回用VOID.調(diào)用如下:
  1. SELECT str
  2. FROM   strTable
  3. WHERE regex1('\w* = (\d|0x00);', str) = 1
復(fù)制代碼
創(chuàng)建DB2函數(shù)的DDL如下:
  1. CREATE FUNCTION regex1(pattern VARCHAR(2048), string CLOB(10M))
  2.     RETURNS INTEGER
  3.     SPECIFIC regexSimple
  4.     EXTERNAL NAME 'regexUdf!regexpSimple'
  5.     LANGUAGE C
  6.     PARAMETER STYLE DB2SQL
  7.     DETERMINISTIC
  8.     NOT FENCED
  9.     RETURNS NULL ON NULL INPUT
  10.     NO SQL
  11.     NO EXTERNAL ACTION
  12.     ALLOW PARALLEL;
復(fù)制代碼

論壇徽章:
0
5 [報告]
發(fā)表于 2010-10-27 18:18 |只看該作者
所以, 原來的TrimChr函數(shù)需要改成兩個參數(shù),一個是輸入,一個是輸出.

不過我改了一下,編譯時一直有問題,請問有無高人幫改一下.

論壇徽章:
0
6 [報告]
發(fā)表于 2010-10-27 21:51 |只看該作者
問題解決了.

C代碼如下:
  1. #include        <string.h>
  2. #include        <memory.h>
  3. #include        <sqludf.h>

  4. #define        ISSPACE(x) ((x)==' '||(x)=='\r'||(x)=='\n'||(x)=='\f'||(x)=='\b'||(x)=='\t')

  5. void TrimChr( char *String, char *TrimedString )
  6. {
  7.         char        *Tail, *Head;

  8.         for ( Tail = String + strlen( String ) - 1; Tail >= String; Tail -- )
  9.                 if ( !ISSPACE( *Tail ) )
  10.                         break;
  11.         Tail[1] = 0;
  12.         for ( Head = String; Head <= Tail; Head ++ )
  13.                 if ( !ISSPACE( *Head ) )
  14.                         break;
  15.         if ( Head != String )
  16.                 memcpy( String, Head, ( Tail - Head + 2 ) * sizeof( char ) );
  17.         
  18.         strcpy(TrimedString, String);
  19.         return;
  20. }
復(fù)制代碼
這段代碼是借鑒FH的這個貼子的:
http://72891.cn/viewthread.php?tid=277036

編譯命令如下:
  1. cc -c -o TrimChr.o -I ~/sqllib/include TrimChr.c -D_REENTRANT
  2. cc -o TrimChr -shared -fpic TrimChr.o
復(fù)制代碼
請用db2inst1用戶編譯,編譯成功后,將可執(zhí)行文件COPY到 ~/sqllib/function/下,即/home/db2inst1/sqllib/function/下.
  1. cp TrimChr ~/sqllib/function/
復(fù)制代碼
最后到數(shù)據(jù)庫中創(chuàng)建自定義函數(shù):
  1. --DROP FUNCTION TrimChr;

  2. CREATE FUNCTION TrimChr (VARCHAR(400))
  3.                            RETURNS VARCHAR(400)  
  4.                            EXTERNAL NAME '/home/db2inst1/sqllib/function/TrimChr!TrimChr'
  5.                            LANGUAGE C  
  6.                            NULL CALL  
  7.                            PARAMETER STYLE DB2SQL  
  8.                            NO SQL  
  9.                            DETERMINISTIC  
  10.                            NO EXTERNAL ACTION
  11.                            NOT FENCED;

  12. GRANT EXECUTE ON FUNCTION TRIMCHR(VARCHAR(400)) TO PUBLIC;
復(fù)制代碼
然后就可以直接使用此函數(shù)了:
  1. values TrimChr('                 aaa          bbb                          ');
復(fù)制代碼
本人不懂C,主要是不斷的查資料,不斷的做實驗而成功的.

在此還要請假一個問題:
定義宏使用了如下語句:
  1. #define        ISSPACE(x) ((x)==' '||(x)=='\r'||(x)=='\n'||(x)=='\f'||(x)=='\b'||(x)=='\t')
復(fù)制代碼
能否用ASCII碼代替"\t","\f"這些?因為我想將宏改成所有ASCII碼在0~32之間的值.

論壇徽章:
0
7 [報告]
發(fā)表于 2010-10-28 19:32 |只看該作者
本帖最后由 nees 于 2010-10-28 19:36 編輯

笨辦法:
  1. #define        ISSPACE(x) ((x)==0x00 ||(x)==0x01 ||(x)==0x02 ||(x)==0x03 ||(x)==0x04 ||(x)==0x05 ||(x)==0x06 ||(x)==0x07 ||(x)==0x08 ||(x)==0x09 ||(x)==0x0A ||(x)==0x0B ||(x)==0x0C ||(x)==0x0D ||(x)==0x0E ||(x)==0x0F ||(x)==0x10 ||(x)==0x11 ||(x)==0x12 ||(x)==0x13 ||(x)==0x14 ||(x)==0x15 ||(x)==0x16 ||(x)==0x17 ||(x)==0x18 ||(x)==0x19 ||(x)==0x1A ||(x)==0x1B ||(x)==0x1C ||(x)==0x1D ||(x)==0x1E ||(x)==0x1F ||(x)==0x20 )
復(fù)制代碼
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP