2017-03-03 50 views
-2

我主要是一個.NET程序員,偶爾會構建MS SQL Server存儲過程。在Oracle中構建選擇存儲過程12

我需要在Oracle中構建一個過程來根據一個或多個參數選擇並返回一些記錄。我已經嘗試過建設一個,但已經挫敗了。

這裏是什麼,我想創建一個例子:

CREATE OR REPLACE PROCEDURE P_TS_COLLISIONS_SEARCH(
     county IN VARCHAR2, 
     township IN VARCHAR2, 
     col_MRN IN VARCHAR2, 
     answer OUT VARCHAR2) 

AS 
BEGIN 
    SELECT COLLISION_MASTER_RECORD_NUMBER, CITY, ROAD_NAME 
     INTO answer 
     FROM DWOBDEV.OBIEE_TS_COLLISION_FACT_VW 
    WHERE COLLISION_MASTER_RECORD_NUMBER = col_MRN 
    AND TOWNSHIP = township 
    AND COUNTY = county; 

END P_TS_COLLISIONS_SEARCH; 

我得到這些錯誤:

錯誤(9,5):PL/SQL:SQL語句忽略錯誤(11 ,7):PL/SQL: ORA-00947:值不足

我該如何在Oracle 12中構建這個?

+0

這個問題不顯示任何工作或研究。這裏是一個開始的好地方。 https://www.google.com/search?q=how+to+create+a+stored+procedure+in+oracle+with+parameters&ie=utf-8&oe=utf-8 –

+3

嘗試運行中的查詢程序;它會給出3列的結果。在你的過程中,你試圖把這3個值放在一個標量變量中,所以......另外,請注意,如果你的查詢將給出多於一行,標量變量將不足以承載結果 – Aleksej

+0

如果你只想要一個返回結果到提示的查詢,請嘗試如下所示:http://stackoverflow.com/a/40360471/230471 –

回答

1

你有幾個問題。

  • 您正在選擇三列INTO單列。如果您使用它來返回單個行,則必須將列數與所選變量的數量相匹配。
  • 您在結果中選擇了id,但您已將其作爲輸入值。重新選擇它將是多餘的。
  • 此外,你似乎已經傳入一個ID,目前還不清楚這是否是一個PK,如果是,你不需要查詢額外的值。如果僅傳入一個ID參數來獲取特定行,然後再使用其他參數來匹配其他列值,則會更有意義。

這是您的proc的一個版本,它的工作原理。如果您打算返回多行,則需要更改爲返回一個光標。使用文檔/網頁搜索來查找示例。

create table OBIEE_TS_COLLISION_FACT_VW 
(collision_master_record_number number, 
county varchar2(50), 
township varchar2(50), 
city varchar2(50), 
road_name varchar2(50)); 

insert into obiee_ts_collision_fact_vw values (1, 'WINCHESTER',  'SPRINGFIELD', 'MOSCOW', 'STATION'); 

CREATE OR REPLACE PROCEDURE P_TS_COLLISIONS_SEARCH(
    county IN VARCHAR2, 
    township IN VARCHAR2, 
    col_MRN IN VARCHAR2, 
    city_o OUT VARCHAR2, 
    road_name_o OUT VARCHAR2) 
AS 
BEGIN 
    SELECT CITY, ROAD_NAME 
     INTO city_o, road_name_o 
     FROM OBIEE_TS_COLLISION_FACT_VW 
    WHERE COLLISION_MASTER_RECORD_NUMBER = col_MRN 
    AND TOWNSHIP = township 
    AND COUNTY = county; 

END P_TS_COLLISIONS_SEARCH; 

declare 
    l_id number := 1; 
    l_township VARCHAR2(50) := 'TOWNSHIP'; 
    l_county VARCHAR2(50) := 'COUNTY'; 
    l_city varchar2(50); 
    l_road_name varchar2(50); 
begin 
    P_TS_COLLISIONS_SEARCH(l_county, l_township, l_id, l_city, l_road_name); 
    dbms_output.put_line(l_city||'|'||l_road_name); 
end; 
0

一種猜測,因爲我不知道你想要什麼樣的輸出,但也許這的位:

create or replace procedure p_ts_collisions_search 
    (p_col_mrn obiee_ts_collision_fact_vw.collision_master_record_number%type 
    , p_township obiee_ts_collision_fact_vw.township%type 
    , p_county obiee_ts_collision_fact_vw.county%type) 
as 
    rc sys_refcursor; 
begin 
    open rc for 
     select collision_master_record_number 
      , city 
      , road_name 
     from obiee_ts_collision_fact_vw 
     where collision_master_record_number = p_col_mrn 
     and township = p_township 
     and county = p_county; 

    dbms_sql.return_result(rc); 
end; 

注意,我前綴我的參數與p_從區分它們數據庫列,因爲and township = township並沒有達到很多。 (另一種方法是用程序名稱標記它們,例如p_ts_collisions_search.township。)

虛擬數據:

create view obiee_ts_collision_fact_vw 
as 
select 1 as collision_master_record_number 
    , 'London' as city 
    , 'Bond Street' as road_name 
    , 'West End' as township 
    , 'Lalaland' as county 
from dual; 

演示在SQL * Plus:

SQL> exec p_ts_collisions_search(1, 'West End', 'Lalaland'); 

PL/SQL procedure successfully completed. 

ResultSet #1 

COLLISION_MASTER_RECORD_NUMBER CITY ROAD_NAME 
------------------------------ ------ ----------- 
          1 London Bond Street 

但是,它不會到處工作,因爲客戶需要能夠處理隱含的結果:

SQL> call p_ts_collisions_search(1, 'West End', 'Lalaland'); 
call p_ts_collisions_search(1, 'West End', 'Lalaland') 
    * 
ERROR at line 1: 
ORA-29478: Implicit result cannot be returned through this statement. 
ORA-06512: at "SYS.DBMS_SQL", line 2785 
ORA-06512: at "SYS.DBMS_SQL", line 2779 
ORA-06512: at "WILLIAM.P_TS_COLLISIONS_SEARCH", line 17 

或者,您可以通過out參數明確返回結果集:

create or replace procedure p_ts_collisions_search 
    (p_col_mrn obiee_ts_collision_fact_vw.collision_master_record_number%type 
    , p_township obiee_ts_collision_fact_vw.township%type 
    , p_county obiee_ts_collision_fact_vw.county%type 
    , p_results out sys_refcursor) 
as 
begin 
    open p_results for 
     select collision_master_record_number 
      , city 
      , road_name 
     from obiee_ts_collision_fact_vw 
     where collision_master_record_number = p_col_mrn 
     and township = p_township 
     and county = p_county; 
end; 

演示:

SQL> var results refcursor 
SQL> set autoprint on 
SQL> exec p_ts_collisions_search(1, 'West End', 'Lalaland', :results); 

PL/SQL procedure successfully completed. 

COLLISION_MASTER_RECORD_NUMBER CITY ROAD_NAME 
------------------------------ ------ ----------- 
          1 London Bond Street 
+0

感謝所有的輸入!這非常有幫助! –