0

我有一个存储在表中的冲突矩阵。我正在尝试查找值 table[course1][course2] 但 sql 拒绝合作。

这根本不起作用:说无效的列索引,但不知道为什么。

CREATE OR REPLACE PROCEDURE procedure1(course1    IN  VARCHAR2,
                                       course2    IN  VARCHAR2,
                                       conflicted OUT VARCHAR2) AS
  BEGIN

    EXECUTE IMMEDIATE 'SELECT :col1 FROM conflict_matrix_male WHERE course = :col2'
    INTO conflicted
    USING course1, course2;

    dbms_output.put_line(conflicted);
  END procedure1;

所以我尝试这样做:

CREATE OR REPLACE PROCEDURE procedure1(course1 IN VARCHAR2,
                                       course2 IN VARCHAR2) AS
  conflicted1 VARCHAR2(200);
  BEGIN

    EXECUTE IMMEDIATE 'SELECT :col1 FROM conflict_matrix_male WHERE course = :col2'
    INTO conflicted1
    USING course1, course2;

    dbms_output.put_line(conflicted1);
  END procedure1;

这会编译并运行,但它会返回您传递给 course1 的任何内容,而不是该列中的值。它不会动态地将变量的内容替换到查询中。

我最后一次尝试是这样的:

CREATE OR REPLACE PROCEDURE checkconflict(course1    IN  VARCHAR2,
                                          course2    IN  VARCHAR2,
                                          conflicted OUT VARCHAR2) AS
  query_str VARCHAR2(1000);
  BEGIN

    query_str := 'SELECT ' || course2 ||
                 ' FROM conflict_matrix_male WHERE course = ''' || course1 || ''';';

    dbms_output.put_line(query_str);

    EXECUTE IMMEDIATE query_str INTO conflicted;

    dbms_output.put_line(conflicted);

  END checkconflict;

我运行了第一个打印的 sql 查询dbms_output,它运行良好。但该程序不起作用。我认为错误是一个简单的错误,但我不知道它是什么。

编辑:

存储的内容有点像邻接矩阵。列名是除第一列之外的课程名称。第一列名为 course。它看起来有点像这样。

     课程 CCES1234 CEEN1235 GEEN8234 冲突
     CCES1234 1 1 0 2
     CEEN1235 0 1 0 1
     GEEN8234 1 1 1 3

但要大得多。我的目标是能够取两门课程的名称并返回值。

例如:

  • checkConflict('CCES1234', 'CEEN1235')应该返回 0
  • checkConflict('Geen8234', 'CCES1234')应该返回 1。
4

3 回答 3

3

在您的第一个示例中,您使用列名作为参数。你不能这样做。参数只能用于替换值,不能用于替换列名或表名。

编辑:查看您的新编辑,现在很明显 course1 是一列 NAME,而 course2 是一列 VALUE。所以你想要的,似乎是这样的:

CREATE OR REPLACE PROCEDURE procedure1 (course1 IN VARCHAR2, course2 IN VARCHAR2,             
Conflicted OUT VARCHAR2) IS
BEGIN
EXECUTE IMMEDIATE
'SELECT ' || course1 || ' FROM conflict_matrix_male WHERE course = :crs2'
USING course2
INTO Conflicted;

DBMS_OUTPUT.PUT_LINE(Conflicted);
END;
于 2013-11-11T12:11:59.030 回答
1
create or replace 
procedure CHECKCONFLICT
(
    COURSE1    in varchar2,
    COURSE2    in varchar2,
    Conflicted out varchar2
) as
query1 varchar2(200);
begin
    query1:= 'select ' || COURSE2 || ' from Conflict_matrix_male where course =''' ||    Course1 || '''';
    execute immediate query1
    into conflicted;
    dbms_output.put_line(conflicted);
 end;

小心使用单引号和分号。另外,为什么不使用函数?我总是发现它们更容易使用。

create or replace 
function  CHECKCONFLICT4
(
    COURSE1    in varchar2,
    COURSE2    in varchar2
) 
return number
is Conflicted number;
query1 varchar2(200);
begin
    query1:= 'select ' || COURSE2 || ' from Conflict_matrix_male where course =''' || Course1 || '''';
    execute immediate query1
    into conflicted;
    return conflicted;
end;
于 2013-11-11T20:12:48.270 回答
1

在你的最后一个例子中,你倒置course2and course1,所以我认为

query_str := 'select '|| COURSE2 ||' from Conflict_matrix_male where course  = ''' || Course1 || ''';';

应该

query_str := 'select '|| COURSE1 ||' from Conflict_matrix_male where course  = ''' || Course2 || ''';';

但是您也可以使用绑定,只是不能用于列名:

execute immediate 'Select '||course1||' from conflict_matrix_male where course = :col2'  
  into conflicted using course2;
于 2013-11-11T12:28:09.577 回答