存储 with 时出现日期比较错误
Date comparison error when storing with into
我几乎完成了昨天开始的程序,但在最后一步我发现了一个问题,只有在使用 if 子句进行比较时才会发生。如果您引入足球联赛轮次和球队名称,该程序将显示一场比赛的所有信息。我将足球比赛 ID 存储在 idp 上,以便以后在球队是主队或客队时进行比较,并且日期与可用的两轮比赛之一相匹配(if 子句将不同的日期设置为名为 FECHA 的变量,如果它是一个或两个)。问题是,如果我尝试手动检查 FECHA 或西班牙语日期,它会起作用,但如果我尝试使用 if 路径,则会出现错误,声称:
你能帮我解决吗?非常感谢!
create or replace PROCEDURE COMPROBARPARTIDO(JORNADA IN NUMBER, EQUIPO IN VARCHAR2) AS
FECHA DATE;
IDLOCAL NUMBER;
IDP NUMBER;
NUMAUX NUMBER;
NUMAUX2 NUMBER;
GOLAUX NUMBER;
GOLOC NUMBER;
GOLVI NUMBER;
BEGIN
NUMAUX:=0;
NUMAUX2:=0;
IF JORNADA = 1 THEN
FECHA := TO_DATE('2021-03-04','yyyy-mm-dd');
ELSIF JORNADA = 2 THEN
FECHA := TO_DATE('2021-03-13','yyyy-mm-dd');
ELSE
DBMS_OUTPUT.PUT_LINE('ERROR');
END IF;
SELECT DISTINCT P.ID INTO IDP
FROM PARTIDO P
INNER JOIN EQUIPO EL
ON P.ID_LOCAL =EL.ID
INNER JOIN EQUIPO EV
ON P.ID_VISITANTE = EV.ID
WHERE P.FECHA = FECHA AND (EV.NOMBRE =EQUIPO OR EL.NOMBRE=EQUIPO);
你正在做:
WHERE P.FECHA = FECHA
If a SQL statement references a name that belongs to both a column and either a local variable or formal parameter, then the column name takes precedence.
所以这意味着条件等同于:
WHERE P.FECHA = P.FECHA
始终为真(除非 P.FECHA
为空)。这意味着您将找到 (EV.NOMBRE =EQUIPO OR EL.NOMBRE=EQUIPO)
所在的所有行,而不管 P.FECHA
值如何。这给了你比你预期更多的行;当您使用 select ... into ...
时,查询必须 return 恰好一行,并且当您对日期进行硬编码时可能会这样做。
您应该显式地在变量名称前加上过程名称前缀以赋予它上下文:
WHERE P.FECHA = COMPROBARPARTIDO.FECHA
或者重命名你的局部变量;为局部变量名称添加 L_
前缀和为参数名称添加 P_
是相当常见的,例如,以将它们与列名称区分开来:
create or replace PROCEDURE COMPROBARPARTIDO(P_JORNADA IN NUMBER, P_EQUIPO IN VARCHAR2) AS
L_FECHA DATE;
...
并更改所有引用以匹配:
WHERE P.FECHA = L_FECHA
我几乎完成了昨天开始的程序,但在最后一步我发现了一个问题,只有在使用 if 子句进行比较时才会发生。如果您引入足球联赛轮次和球队名称,该程序将显示一场比赛的所有信息。我将足球比赛 ID 存储在 idp 上,以便以后在球队是主队或客队时进行比较,并且日期与可用的两轮比赛之一相匹配(if 子句将不同的日期设置为名为 FECHA 的变量,如果它是一个或两个)。问题是,如果我尝试手动检查 FECHA 或西班牙语日期,它会起作用,但如果我尝试使用 if 路径,则会出现错误,声称:
create or replace PROCEDURE COMPROBARPARTIDO(JORNADA IN NUMBER, EQUIPO IN VARCHAR2) AS
FECHA DATE;
IDLOCAL NUMBER;
IDP NUMBER;
NUMAUX NUMBER;
NUMAUX2 NUMBER;
GOLAUX NUMBER;
GOLOC NUMBER;
GOLVI NUMBER;
BEGIN
NUMAUX:=0;
NUMAUX2:=0;
IF JORNADA = 1 THEN
FECHA := TO_DATE('2021-03-04','yyyy-mm-dd');
ELSIF JORNADA = 2 THEN
FECHA := TO_DATE('2021-03-13','yyyy-mm-dd');
ELSE
DBMS_OUTPUT.PUT_LINE('ERROR');
END IF;
SELECT DISTINCT P.ID INTO IDP
FROM PARTIDO P
INNER JOIN EQUIPO EL
ON P.ID_LOCAL =EL.ID
INNER JOIN EQUIPO EV
ON P.ID_VISITANTE = EV.ID
WHERE P.FECHA = FECHA AND (EV.NOMBRE =EQUIPO OR EL.NOMBRE=EQUIPO);
你正在做:
WHERE P.FECHA = FECHA
If a SQL statement references a name that belongs to both a column and either a local variable or formal parameter, then the column name takes precedence.
所以这意味着条件等同于:
WHERE P.FECHA = P.FECHA
始终为真(除非 P.FECHA
为空)。这意味着您将找到 (EV.NOMBRE =EQUIPO OR EL.NOMBRE=EQUIPO)
所在的所有行,而不管 P.FECHA
值如何。这给了你比你预期更多的行;当您使用 select ... into ...
时,查询必须 return 恰好一行,并且当您对日期进行硬编码时可能会这样做。
您应该显式地在变量名称前加上过程名称前缀以赋予它上下文:
WHERE P.FECHA = COMPROBARPARTIDO.FECHA
或者重命名你的局部变量;为局部变量名称添加 L_
前缀和为参数名称添加 P_
是相当常见的,例如,以将它们与列名称区分开来:
create or replace PROCEDURE COMPROBARPARTIDO(P_JORNADA IN NUMBER, P_EQUIPO IN VARCHAR2) AS
L_FECHA DATE;
...
并更改所有引用以匹配:
WHERE P.FECHA = L_FECHA