oracle decode 01427,錯誤的ORA-01427:單行子查詢返回多個行。

I'm getting the error [ORA-01427: single-row subquery returns more than one row] when I execute a query. I have a query structured like so:

當執行查詢時,我將得到錯誤[ORA-01427:單行子查詢返回多個行]。我有一個這樣的查詢結構:

SELECT LV.PRICE,

(SELECT C.MODEL_NAME FROM CARS C WHERE C.MODEL_ID = LV.MODEL_ID) as MODEL_NAME

FROM LEDGER_VIEW LV

WHERE LV.PRICE < 500

It's breaking on the nested select. I know the logic both in the view and in this query is correct, and that there's no chance of the nested select returning more than one row. The CARS table's MODEL_ID is a unique field. If I execute the query without the nested select it doesn't return this error.

它在嵌套的select中打開。我知道視圖中和這個查詢中的邏輯都是正確的,而且嵌套的select返回的次數也不可能超過一行。CARS表的MODEL_ID是一個獨特的字段。如果我在沒有嵌套select的情況下執行查詢,它不會返回這個錯誤。

The LEDGER_VIEW is a view built on top of another view. Is it possible that these stacked views are buggy in Oracle 10g? I don't know how else to debug this problem.

LEDGER_VIEW是構建在另一個視圖之上的視圖。在Oracle 10g中,這些堆疊的視圖有可能是錯誤的嗎?我不知道如何調試這個問題。

I am aware I could change this particular query to a join rather than a nested select, but I'd like to know why this is happening because I use nested queries in other places where it is not so easily modifiable.

我知道我可以將這個特定的查詢改為一個join,而不是一個嵌套的select,但是我想知道為什么會發生這種情況,因為我在其他地方使用嵌套的查詢,因為它不太容易修改。

EDIT: Here's the really strange thing. The LEDGER_VIEW is, as I said, built on top of another view. As a test, I copied the nested view's SQL directly into the SQL of the SQL of LEDGER_VIEW, in place of the nested view, and it returned with no errors (as expected). This seems to confirm to me that there is some buggy behavior either with nested views or with the combination of nested views + database links.

編輯:這是非常奇怪的事情。正如我說的,LEDGER_VIEW是建立在另一個視圖之上的。作為一個測試,我將嵌套視圖的SQL直接復制到LEDGER_VIEW的SQL SQL中,代替嵌套視圖,並且沒有出現錯誤(如預期的那樣)。這似乎證實了我認為有一些bug的行為是嵌套的視圖,或者是嵌套視圖+數據庫鏈接的組合。

5 个解决方案

#1

2

I am unable to recreate via a creation of a stacked view. (althoug RedFilters will find the culprit)

我無法通過創建一個堆棧視圖來重新創建。(紅色過濾系統會找到罪魁禍首)

CREATE TABLE t1

(

t1_id NUMBER ,

txt VARCHAR2( 50 ),

CONSTRAINT t1_pk PRIMARY KEY( t1_id )

) ;

CREATE TABLE t2

(

t2_id NUMBER ,

t1_id NUMBER ,

price NUMBER( 10, 4 ) ,

CONSTRAINT t2_pk PRIMARY KEY( t2_id ),

CONSTRAINT t2_fk FOREIGN KEY( t1_id ) REFERENCES t1( t1_id )

);

insert into t1(t1_id, txt) values(1,'fit');

insert into t1(t1_id, txt) values(2,'focus');

insert into t1(t1_id, txt) values(3,'golf');

insert into t1(t1_id, txt) values(4,'explorer');

insert into t1(t1_id, txt) values(5,'corolla');

insert into t2(t2_id, t1_id, price) values(1,1,17000);

insert into t2(t2_id, t1_id, price) values(2,2,16000);

insert into t2(t2_id, t1_id, price) values(3,3,22000);

insert into t2(t2_id, t1_id, price) values(4,4,31000);

insert into t2(t2_id, t1_id, price) values(5,5,17000);

create view t1_view as select * from t1;

create view t2_view as select * from t2;

create view t_stacked_view as

select t1_view.txt ,

t2_view.price ,

t1_view.t1_id

from t1_view

left join

t2_view

on t1_view.t1_id = t2_view .t1_id

;

--stacked view test

select t1_view.txt ,

(select t_stacked_view.price

from t_stacked_view

where t1_view.t1_id = t_stacked_view .t1_id) price

from t1_view ;

--or better yet, just drop the row level query

select t1_view.txt ,

t2_view.price

from t1_view

left join

t2_view

on t1_view.t1_id = t2_view .t1_id

;

But that begs the question, why are you doing the row level query here? While 10g ought to optimize them the same, I have always found it easier to write queries as below, both for readability, maintainability, and to specifically avoid the error you are having (is it always, 3 years down the road, guaranteed by the application (both in the db and the calling app) that you cannot have a condition that will cause this error? One rouge statement gets in and your entire app dies?

但這就引出了一個問題,為什么要在這里執行行級查詢?雖然他們10 g應該優化一樣,我總是發現它更容易編寫查詢如下,對於可讀性,可維護性,特別避免錯誤你(總是,3年后,保證應用程序(在db和調用應用程序),不能有條件將導致這個錯誤嗎?你的整個應用程序都死了?

SELECT LV.PRICE,

c.model_name

FROM LEDGER_VIEW LV

LEFT /* OR INNER */ JOIN CARS C

ON C.MODEL_ID = LV.MODEL_ID

WHERE LV.PRICE < 500

#2

4

Your subquery is returning multiple rows. Use the query below to find out which MODELID values in the Car table are duplicated:

子查詢返回多行。使用下面的查詢來找出汽車表中哪些MODELID值是重復的:

select MODELID as CarsModelID, count(*) as Count

from cars

where MODELID in (

select MODEL_ID

from LEDGER_VIEW

WHERE LV.PRICE < 500

)

group by MODELID

having count(*) > 1

#3

1

I suggest using RedFilter's answer to check whether there are multiple cars with a given MODEL_ID.

我建議使用RedFilter的答案來檢查是否有多個帶有給定MODEL_ID的汽車。

If you're absolutely certain that CARS.MODEL_ID is unique, then it implies that the error message is generated by selection from LEDGER_VIEW - so try running the equivalent query without the subquery on CARS, like so:

如果你絕對肯定那輛車。MODEL_ID是惟一的,它意味着錯誤消息是由LEDGER_VIEW的選擇生成的——因此,嘗試運行等效查詢,而不需要對CARS進行子查詢,比如:

SELECT LV.PRICE

FROM LEDGER_VIEW LV

WHERE LV.PRICE < 500

If you still see the same error (you should, if CARS.MODEL_ID is unique) you will need to debug LEDGER_VIEW - ie. check for sub-queries returning multiple rows in LEDGER_VIEW and the underlying views it is based on.

如果您仍然看到相同的錯誤(如果是汽車的話)。MODEL_ID是唯一的)您需要調試LEDGER_VIEW - ie。檢查在LEDGER_VIEW中返回多行的子查詢以及它基於的底層視圖。

Creating views based on views is possible in most forms of SQL, but it is usually a bad idea - for this very reason.

在大多數SQL形式中創建基於視圖的視圖是可能的,但這通常是一個壞主意——出於這個原因。

#4

0

Try forcing your subquery to return a single result by appending rownum = 1, like this:

嘗試強制您的子查詢通過追加rownum = 1返回單個結果,如下所示:

SELECT LV.PRICE,

(SELECT C.MODEL_NAME FROM CARS C WHERE C.MODEL_ID = LV.MODEL_ID AND ROWNUM = 1) as MODEL_NAME

FROM LEDGER_VIEW LV

WHERE LV.PRICE < 500

It will probably work and if it does, you will know that your subquery returns multiple rows, which judging by the error code it should be. Of course this is not a solution so you might have to fix your data in cars table to actually solve the problem. Leaving and rownum = 1 will eliminate the error if model_id is duplicated again, preventing you from noticing the problem.

它可能會起作用,如果它成功了,您將知道您的子查詢將返回多行,這是由錯誤代碼判斷的。當然,這不是一個解決方案,所以您可能需要在cars表中修復您的數據,以實際解決問題。如果model_id再次被復制,那么離開和rownum = 1將消除錯誤,防止您注意到問題。

#5

0

select

a.account_number,

a.party_id,

a.TRX_NUMBER,

a.trx_date,

a.order_number,

adv.unapplied_amt,

a.Finance,

a.customer_name,a.PARTY_NAME,

a.customer_number,a.contact_number,

a.name,

a.Aging,

a.transaction_type,

a.exec_name,

a.team_leader,

sum(a.O_SAmount),

(case when (trunc(sysdate) - trunc(a.trx_date)) <=:ag1 then sum(a.O_SAmount) else 0 end ) bucket1,--"

(case when (trunc(sysdate) - trunc(a.trx_date)) between :ag1+1 and :ag2 then sum(a.O_SAmount) else 0 end ) bucket2,--:ag1+1 || "to" || :ag2,

(case when (trunc(sysdate) - trunc(a.trx_date)) between :ag2+1 and :ag3 then sum(a.O_SAmount) else 0 end ) bucket3,--:ag2+1 || "to" || :ag3,

(case when (trunc(sysdate) - trunc(a.trx_date)) >:ag3 then sum(a.O_SAmount) else 0 end ) bucket4,

:AS_ON_date

from

(select distinct hca.account_number,hp.party_id,--rcta.CUSTOMER_TRX_ID,

--rcta.trx_number,rcta.trx_date,apsa.due_date,

(

select distinct

--ooha.order_number,

rcta.trx_number

--to_char(rcta.trx_date,'DD-MON-YYYY') trx_date

from

ra_customer_trx_all rcta,

oe_order_headers_all ooh,

oe_order_lines_all oola,

--ra_customer_trx_all rcta,

ra_customer_trx_lines_all rctla,

ra_cust_trx_types_all rctta

--ra_customer_trx_lines_all rctl

where 1=1

AND ooh.header_id = oola.header_id

--AND ooh.order_number = '111111010101698'

AND ooh.order_number=oohA.order_number

AND TO_CHAR (ooh.order_number) = rcta.ct_reference

AND rcta.customer_trx_id = rctla.customer_trx_id

AND rctla.inventory_item_id = oola.inventory_item_id

and rcta.CUST_TRX_TYPE_ID = rctta.cust_trx_type_id

and rcta.org_id = rctta.org_id

and rctta.type like 'INV'

and oola.ordered_item LIKE 'MV%'

AND oola.attribute3 = 'Y'

AND ooh.flow_status_code <> 'ENTERED'

AND oola.flow_status_code <> 'CANCELLED'

)TRX_NUMBER,

(select distinct

--ooha.order_number,

--rcta.trx_number

rcta.trx_date

from

ra_customer_trx_all rcta,

oe_order_headers_all ooh,

oe_order_lines_all oola,

--ra_customer_trx_all rcta,

ra_customer_trx_lines_all rctla,

ra_cust_trx_types_all rctta

--ra_customer_trx_lines_all rctl

where 1=1

AND ooh.header_id = oola.header_id

--AND ooh.order_number = '111111010101698'

AND ooh.order_number=oohA.order_number

AND TO_CHAR (ooh.order_number) = rcta.ct_reference

AND rcta.customer_trx_id = rctla.customer_trx_id

AND rctla.inventory_item_id = oola.inventory_item_id

and rcta.CUST_TRX_TYPE_ID = rctta.cust_trx_type_id

and rcta.org_id = rctta.org_id

and rctta.type like 'INV'

and oola.ordered_item LIKE 'MV%'

AND oola.attribute3 = 'Y'

AND ooh.flow_status_code <> 'ENTERED'

AND oola.flow_status_code <> 'CANCELLED'

)TRX_Date,

rcta.INTERFACE_HEADER_ATTRIBUTE1 order_number,

ooha.attribute10 Finance,

f.customer_name,HP.PARTY_NAME,

TO_NUMBER(f.customer_number)customer_number,hp.primary_phone_number contact_number,--csi.incident_number,

--cii.instance_number,

haou.name,

--sum(acr.amount) Advance,--rcta.CUST_TRX_TYPE_ID,--acr.cash_receipt_id,

--sum(abs((apsa.AMOUNT_DUE_REMAINING-nvl(acr.amount,0)))) "O_SAmount",

apsa.AMOUNT_DUE_REMAINING O_SAmount,

--sum(abs((apsa.AMOUNT_DUE_REMAINING))) "O_SAmount",

round(months_between(sysdate,rcta.trx_date)*30) Aging,

--(case when ((round(months_between(sysdate,rcta.trx_date)*30)>=0) or (round(months_between(sysdate,rcta.trx_date)*30)<:aging1 then apsa.amount_due_remaining end to>

--(case when (trunc(sysdate) - trunc(apsa.Due_Date)) <=:ag1 then apsa.AMOUNT_DUE_REMAINING else 0 end ) bucket1,--"

--(case when (trunc(sysdate) - trunc(apsa.Due_Date)) between :ag1+1 and :ag2 then apsa.AMOUNT_DUE_REMAINING else 0 end ) bucket2,--:ag1+1 || "to" || :ag2,

--(case when (trunc(sysdate) - trunc(apsa.Due_Date)) between :ag2+1 and :ag3 then apsa.AMOUNT_DUE_REMAINING else 0 end ) bucket3,--:ag2+1 || "to" || :ag3,

--(case when (trunc(sysdate) - trunc(apsa.Due_Date)) >:ag3 then apsa.AMOUNT_DUE_REMAINING else 0 end ) bucket4,

--apsa.amount_due_original,

--TO_NUMBER(apsa.AMOUNT_DUE_REMAINING)AMOUNT_DUE_REMAINING,

rctta.name transaction_type,

PAPF.full_name||'-'||PAPF.EMPLOYEE_NUMBER exec_name,

ooha.attribute9 team_leader,

:AS_ON_date

from ra_customer_trx_all rcta,

oe_order_headers_all ooha,

hz_cust_accounts hca,

hz_parties hp,

--cs_incidents_all_b csi,

--csi_item_instances cii,

hr_all_organization_units haou,

ar_cash_receipts_all acr,

ar_receivable_applications_all aaa,

ra_cust_trx_types_all RCTTA,

hr.per_all_people_f papf,

ar_customers f,

ar_payment_schedules_all apsa,

jtf.JTF_RS_SALESREPS jrs

where 1=1

--and INTERFACE_HEADER_ATTRIBUTE1 like '111111060100538'

--and INTERFACE_HEADER_ATTRIBUTE1 like '111111010105402'

--and INTERFACE_HEADER_ATTRIBUTE1 like '111111010102791'

and rcta.ct_reference(+)=TO_CHAR(ooha.order_number)

AND f.customer_id = (rcta.bill_to_customer_id)

and f.customer_id=hca.cust_account_id

and hca.party_id=hp.party_id

and haou.organization_id=rcta.INTERFACE_HEADER_ATTRIBUTE10

--and hp.party_id=cii.owner_party_id

--and csi.inventory_item_id=cii.inventory_item_id

--and csi.inv_organization_id=haou.organization_id

--and haou.organization_id=nvl(:location,haou.organization_id)

and ooha.SHIP_FROM_ORG_ID=nvl(:location,haou.organization_id)

AND RCTTA.NAME like :transaction_type||'%'

--decode(:org_id,null,null,(select name from ar_cash_receipts_all where organization_id = :org_id)) ||'%')

and rcta.trx_date<=to_date(:AS_ON_date)

--AND RCTTA.NAME=NVL(:TRANS_TYPE,RCTTA.NAME)

and rcta.org_id=nvl(:org_id,rcta.org_id)

--and f.customer_name like 'VIKAS SATAV'

and aaa.applied_customer_trx_id(+)=rcta.customer_trx_id

and aaa.cash_receipt_id=acr.cash_receipt_id(+)

and rcta.status_trx like 'OP'

and rcta.CUST_TRX_TYPE_ID=rctta.CUST_TRX_TYPE_ID

and apsa.CUSTOMER_TRX_ID=rcta.CUSTOMER_TRX_ID

and TO_NUMBER(apsa.AMOUNT_DUE_REMAINING) >0

--and hp.party_id=papf.party_id(+)

and jrs.salesrep_id = ooha.SALESREP_ID

and jrs.ORG_ID = ooha.ORG_ID

and jrs.PERSON_ID = papf.PERSON_ID(+)

) a,

(

select

b.order_number,

sum(b.AMOUNT_APPLIED) unapplied_amt

from

(select distinct to_char(ooha.order_number) order_number,ara.* from

oe_order_headers_all ooha,

oe_payments oe,

ar_receivable_applications_all ara

where 1=1--ooha.order_number = :p_order_num

and oe.header_id=ooha.header_id

and ara.PAYMENT_SET_ID=oe.PAYMENT_SET_ID

and ara.DISPLAY='Y'

and (ara.STATUS like 'OTHER ACC' or ara.STATUS like 'UNAPP') --or ara.STATUS like 'ACC')

) b

group by b.order_number

) adv

where adv.order_number(+)=a.order_number

group by a.account_number,

a.party_id,

a.TRX_NUMBER,

a.trx_date,

a.order_number,

adv.unapplied_amt,

a.Finance,

a.customer_name,a.PARTY_NAME,

a.customer_number,a.contact_number,

a.name,

a.Aging,

a.transaction_type,

a.exec_name,

a.team_leader

order by a.Aging desc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值