2010-08-03 36 views
17

Tôi đang cố gắng viết một truy vấn đơn giản, trong đó tôi khai báo một số biến và sau đó sử dụng chúng trong một câu lệnh chọn trong Oracle. Tôi đã có thể thực hiện việc này trước trong SQL Server với những điều sau đây:Khai báo & Đặt các Biến trong Tuyên bố Chọn

DECLARE @date1 DATETIME 
SET @date1 = '03-AUG-2010' 

SELECT U.VisualID 
FROM Usage u WITH(NOLOCK) 
WHERE U.UseTime > @Date1 

Từ tìm kiếm tôi đã thực hiện, bạn không thể khai báo và đặt các biến như thế này trong câu lệnh Select. Điều này đúng hay tôi đang làm gì đó?

Trả lời

16

Từ tìm kiếm tôi đã thực hiện nó xuất hiện bạn không thể khai báo và thiết lập các biến như thế này trong Chọn phát biểu. Điều này đúng hay tôi đang thiếu một cái gì đó?

Trong Oracle PL/SQL và SQL là hai ngôn ngữ riêng biệt với hai công cụ riêng biệt. Bạn có thể nhúng SQL DML trong PL/SQL, và điều đó sẽ giúp bạn có được các biến. Chẳng hạn như khối PL/SQL ẩn danh sau đây. Lưu ý rằng / ở cuối không phải là một phần của PL/SQL, nhưng yêu cầu SQL * Plus gửi khối trước đó.

declare 
    v_Date1 date := to_date('03-AUG-2010', 'DD-Mon-YYYY'); 
    v_Count number; 
begin 
    select count(*) into v_Count 
    from Usage 
    where UseTime > v_Date1; 
    dbms_output.put_line(v_Count); 
end; 
/

Vấn đề là một khối có nghĩa là tương đương với mã T-SQL của bạn sẽ không hoạt động:

SQL> declare 
    2  v_Date1 date := to_date('03-AUG-2010', 'DD-Mon-YYYY'); 
    3 begin 
    4  select VisualId 
    5  from Usage 
    6  where UseTime > v_Date1; 
    7 end; 
    8/
    select VisualId 
    * 
ERROR at line 4: 
ORA-06550: line 4, column 5: 
PLS-00428: an INTO clause is expected in this SELECT statement 

Để vượt qua các kết quả của một truy vấn ra khỏi một PL/SQL, hoặc là một ẩn danh khối, thủ tục lưu trữ hoặc chức năng được lưu trữ, một con trỏ phải được khai báo, mở và sau đó quay trở lại chương trình gọi. (Ngoài phạm vi trả lời câu hỏi này. EDIT: xem Get resultset from oracle stored procedure)

Công cụ khách hàng kết nối với cơ sở dữ liệu có thể có các biến liên kết riêng. Trong SQL * Plus:

SQL> -- SQL*Plus does not all date type in this context 
SQL> -- So using varchar2 to hold text 
SQL> variable v_Date1 varchar2(20) 
SQL> 
SQL> -- use PL/SQL to set the value of the bind variable 
SQL> exec :v_Date1 := '02-Aug-2010'; 

PL/SQL procedure successfully completed. 

SQL> -- Converting to a date, since the variable is not yet a date. 
SQL> -- Note the use of colon, this tells SQL*Plus that v_Date1 
SQL> -- is a bind variable. 
SQL> select VisualId 
    2 from Usage 
    3 where UseTime > to_char(:v_Date1, 'DD-Mon-YYYY'); 

no rows selected 

Lưu ý ở trên là trong SQL Thêm vào đó, có thể không (có lẽ sẽ không) làm việc trong nhà phát triển Toad PL/SQL, vv Các dòng bắt đầu với biến và exec là SQL Thêm lệnh. Chúng không phải là các lệnh SQL hoặc PL/SQL. Không có hàng nào được chọn vì bảng trống.

+4

+1: Đó không phải là câu trả lời, đó là một * luận án *! –

+0

+1 đồng ý với @OMG Ponies :) – ThinkJet

+0

+1 tương tự như vậy TJ! –

0

Thử chức năng to_date.

+0

tôi về cơ bản cố gắng thiết lập một giá trị ngày (hoặc một giá trị VARCHAR2) và sau đó tham khảo nó trong các tuyên bố chọn. Tôi nghĩ TO_DATE có nhiều chức năng hơn để chuyển đổi một chuỗi thành một ngày của Oracle. –

1

Lệnh SET là TSQL cụ thể - đây là PLSQL tương đương với những gì bạn được đăng:

v_date1 DATE := TO_DATE('03-AUG-2010', 'DD-MON-YYYY'); 

SELECT u.visualid 
    FROM USAGE u 
WHERE u.usetime > v_date1; 

Ngoài ra còn có không cần tiền tố biến với "@"; Tôi có xu hướng tiền tố biến với "v_" để phân biệt giữa các biến & cột/v.v.

Xem this thread about the Oracle equivalent of NOLOCK ...

2

Tôi đã cố gắng này và nó làm việc:

define PROPp_START_DT = TO_DATE('01-SEP-1999') 

select * from proposal where prop_start_dt = &PROPp_START_DT 

 

Các vấn đề liên quan