2015-12-15 138 views
1

我有一個奇怪的問題。COBOL嵌入式SQL

  EXEC SQL SELECT        
     AVG(LER)         
     INTO :LER-MIN        
     FROM CENSUS.WORLDIMR      
    *  WHERE CENSUS.WORLDIMR.COUNTRY LIKE 'L%'  
     END-EXEC.       

這給予了72.2,但是當我使用

WHERE CENSUS.WORLDIMR.COUNTRY LIKE 'L%' 

它給出了00.0。

在SPUFI然而嘗試這種:

select avg(ler)        
from census.worldimr       
where census.worldimr.country like 'L%';  

釋放出71.33333333333。

我做錯了什麼?

這是程序:

000001  PROCESS SQL              
000002  IDENTIFICATION DIVISION.           
000003  PROGRAM-ID. CBL7.             
000004  *--------------------            
000005  ENVIRONMENT DIVISION.            
000006  *--------------------            
000007  CONFIGURATION SECTION.           
000008  INPUT-OUTPUT SECTION.            
000009  FILE-CONTROL.              
000010   SELECT P3OUT ASSIGN TO UT-S-P3OUT.       
000011                   
000012  DATA DIVISION.             
000013  *-------------              
000014  FILE SECTION.              
000015  FD P3OUT               
000016   RECORD CONTAINS 80 CHARACTERS         
000017   LABEL RECORDS ARE OMITTED          
000018   RECORDING MODE F            
000019   DATA RECORD IS PRTREC.          
000020                   
000021  01 PRTREC.              
000022   02 LER-PRT    PIC 99.9.        
000023   02 FILLER    PIC X(76).        
000024                   
000025  WORKING-STORAGE SECTION.           
000026  01 VARS.               
000027   10 LER-MIN    PIC S9(5)V9(1) USAGE COMP-3.   
000028                   
000029    EXEC SQL INCLUDE SQLCA END-EXEC.       
000030  ****************************************************************** 
000031  *  TABLE(CENSUS.WORLDIMR)         * 
000032  ****************************************************************** 
000033   EXEC SQL DECLARE CENSUS.WORLDIMR TABLE      
000034   (REGION       CHAR(5) NOT NULL,   
000035    COUNTRY      CHAR(30) NOT NULL,   
000036    YR        CHAR(4) NOT NULL,   
000037    IMR       DECIMAL(5, 1) NOT NULL,  
000038    IMRM       DECIMAL(5, 1) NOT NULL,  
000039    IMRF       DECIMAL(5, 1) NOT NULL,  
000040    IMR1_4       DECIMAL(5, 1) NOT NULL,  
000041    IMR1_4M      DECIMAL(5, 1) NOT NULL,  
000042    IMR1_4F      DECIMAL(5, 1) NOT NULL,  
000043    IMR_5       DECIMAL(5, 1) NOT NULL,  
000044    IMR_5M       DECIMAL(5, 1) NOT NULL,  
000045    IMR_5F       DECIMAL(5, 1) NOT NULL,  
000046    LER       DECIMAL(5, 1) NOT NULL,  
000047    LERM       DECIMAL(5, 1) NOT NULL,  
000048    LERF       DECIMAL(5, 1) NOT NULL  
000049   ) END-EXEC.             
000050  ****************************************************************** 
000051  * COBOL DECLARATION FOR TABLE CENSUS.WORLDIMR     * 
000052  ****************************************************************** 
000053  01 WORLDIMR.              
000054   10 REGION    PIC X(5).        
000055   10 COUNTRY    PIC X(30).       
000056   10 YR     PIC X(4).        
000057   10 IMR     PIC S9(4)V9(1) USAGE COMP-3.   
000058   10 IMRM     PIC S9(4)V9(1) USAGE COMP-3.   
000059   10 IMRF     PIC S9(4)V9(1) USAGE COMP-3.   
000060   10 IMR1-4    PIC S9(4)V9(1) USAGE COMP-3.   
000061   10 IMR1-4M    PIC S9(4)V9(1) USAGE COMP-3.   
000062   10 IMR1-4F    PIC S9(4)V9(1) USAGE COMP-3.   
000063   10 IMR-5    PIC S9(4)V9(1) USAGE COMP-3.   
000064   10 IMR-5M    PIC S9(4)V9(1) USAGE COMP-3.   
000065   10 IMR-5F    PIC S9(4)V9(1) USAGE COMP-3.   
000066   10 LER     PIC S9(4)V9(1) USAGE COMP-3.   
000067   10 LERM     PIC S9(4)V9(1) USAGE COMP-3.   
000068   10 LERF     PIC S9(4)V9(1) USAGE COMP-3.   
000069                   
000070  PROCEDURE DIVISION.            
000071  *------------------            
000072   EXEC SQL SELECT            
000073    AVG(LER)              
000074    INTO :LER-MIN            
000075    FROM CENSUS.WORLDIMR           
000076    WHERE CENSUS.WORLDIMR.COUNTRY LIKE 'L%'      
000077    END-EXEC.             
000078   OPEN OUTPUT P3OUT.           
000079   MOVE LER-MIN TO LER-PRT.          
000080   WRITE PRTREC.             
000081   CLOSE P3OUT.             
000082   STOP RUN.          
+0

您確定連接到相同的數據庫/服務器嗎? – lad2025

+0

很奇怪。你確定你是連接到相同的數據庫,作爲同一個用戶嗎? – jarlh

+0

是的,我很確定。每次我嘗試使用WHERE CENSUS.WORLDIMR.COUNTRY LIKE'L%'它顯示00.0 – bastel

回答

5

手冊是偉大的事情,尤其是當搜索引擎可以直接打成了他們:

DB2 SQL像

第一點擊應該會引導您通過IBM知識中心向您提供的手冊。它適用於DB2 11.0,所以如果你不使用11.0,你應該做出明顯的改變。

閱讀,你會來:

如果在一個固定長度的字符串變量中指定的模式,任何 尾隨空白被解釋爲模式的一部分。因此, 最好使用長度可變的字符串變量,其長度與模式的長度相同,長度爲 。 如果主機 語言不允許變長字符串變量,請將 模式置於長度爲模式的長度 的固定長度字符串變量中。

有關使用特定 編程語言使用主機變量的更多信息,請參閱主機變量。

您正在使用的語言COBOL不允許長度可變的字符串變量(使其變得如此之快,所以不要抱怨)。

因此,您的LIKE常量(在COBOL中的字面量)需要與所涉及的列的長度相同,並且字面值中的所有附加位置也需要爲%(至少直到嚴格來說,與LIKE匹配的任何數據的實際最大長度)。

或者,使用該長度的COBOL主變量,再次填充尾部%s而不是尾部空格。

或者使用類似varchar的主機變量(COBOL表中的項目包含的數據長度爲雙字節二進制,值爲2,然後爲L%)。

01 varchar-host-variable. 
    05 vhv-length    COMP-5 PIC 9(4). 
    05 vhv-data      PIC XX. 

即使字面擔任您的預期(不閱讀說明書),通常是一個壞主意,有在程序分流「顯著」文字。使用主機變量的第二個原因。

+0

在我的書中,固定長度變量的主要優點是程序的內存佔用量是在編譯時定義的,這使得內存泄漏成爲不可能。使開採真的更安全。但是,是的,它也有一些性能優勢。 – gazzz0x2z

+0

@ gazzz0x2z即使使用變長字段,如果您堅持使用COBOL(受編譯器錯誤影響),您仍無法在Enterprise COBOL中獲取內存泄漏。通過利用,你的意思是劫持程序中的東西?除了在現場工作的人以外,當它只是非常困難時,從外部位置是不可能的。當然,其他不太成熟的操作系統和其他編譯器的里程也不相同。 –

+0

不,我只是在談論那些在同一時間內啓動並觀看數百個過程的人。他們不喜歡看到一個進程吃掉所有對其他人有用的內存空間。劫持,otoh不是語言問題,風險通常在您認爲沒有風險時開始。 – gazzz0x2z