【问题标题】:Show film description with string format以字符串格式显示影片描述
【发布时间】:2021-12-02 10:32:09
【问题描述】:

我有一个任务需要编写一个带有格式的触发语句

这是我的数据库架构:

我的代码是这样写的

CREATE OR REPLACE TRIGGER "BI_FILM_DESP"
BEFORE INSERT ON "FILM"
FOR EACH ROW
DECLARE
RatingFilm VARCHAR2(8);
Seq NUMBER(3);
OriginalL VARCHAR2(20);
Language VARCHAR2(20);
BEGIN
SELECT RATING INTO RatingFilm FROM FILM F;
SELECT COUNT(RATING) INTO Seq FROM FILM F GROUP BY F.RATING;
SELECT LANGUAGE.NAME INTO OriginalL FROM LANGUAGE L WHERE (L.LANGUAGE_ID =: FILM.LANGUAGE_ID);
SELECT LANGUAGE.NAME INTO Language FRoM LANGUAGE L WHERE (L.LANGUAGE_ID =: FILM.LANGUAGE_ID);
SELECT CONCAT(RatingFilm, "-", Seq, ": Originally in", OriginalL, ". Re-released in ", Language, ".");
END;
/

但是它显示错误

我认为很难阅读这些错误,我需要一些帮助来纠正它。提前致谢。


编辑:添加创建表的代码

CREATE TABLE film (
  film_id NUMBER(5) NOT NULL,
  title varchar2(255),
  description varchar2(255),
  release_year NUMBER(4) DEFAULT NULL,
  language_id NUMBER(3) NOT NULL,
  original_language_id NUMBER(3) DEFAULT NULL,
  rental_duration NUMBER(3) DEFAULT 3 NOT NULL,
  rental_rate NUMBER(4,2) DEFAULT '4.99' NOT NULL,
  length NUMBER(5) DEFAULT NULL,
  replacement_cost NUMBER(5,2) DEFAULT '19.99' NOT NULL,
  rating varchar2(8) DEFAULT 'G' NOT NULL,
  special_features varchar2(255) DEFAULT NULL
);

CREATE TABLE language (
  language_id NUMBER(3) NOT NULL,
  name varchar2(20)
);

【问题讨论】:

  • (1) MySQL OracleDB,标记列表已编辑 (2) 在 SELECT LANGUAGE.NAME INTO OriginalL FROM LANGUAGE L WHERE (L.LANGUAGE_ID =: FILM.LANGUAGE_ID); 中,表 FILM 未在 FROM 子句中作为行源提及。 (3) 在基于行的触发器中,您必须参考NEW 伪表来访问当前行值。
  • 1) 在 Oracle 中,字符串应该用单引号 ' 括起来,双引号用于标识符。 2)你不能从任何地方选择,当你需要一些常量时你应该使用from dual。 3) 您不能使用for each row 访问触发器内的同一个表,您将收到变异表错误。 4)select不带过滤器会返回多行,不能放入标量变量。所以要解决的问题太多了,试着一步一步构建你的解决方案。

标签: sql oracle triggers string-concatenation


【解决方案1】:

希望你阅读 astentx 的评论。

您可以/应该这样做。

涉及的表格(仅包含必要的列):

SQL> CREATE TABLE language
  2  (
  3     language_id   NUMBER PRIMARY KEY,
  4     name          VARCHAR2 (20)
  5  );

Table created.

SQL> INSERT INTO language (language_id, name)
  2     SELECT 1, 'English' FROM DUAL
  3     UNION ALL
  4     SELECT 2, 'Croatian' FROM DUAL;

2 rows created.

SQL> CREATE TABLE film
  2  (
  3     film_id                NUMBER PRIMARY KEY,
  4     title                  VARCHAR2 (20),
  5     description            VARCHAR2 (100),
  6     language_id            NUMBER REFERENCES language,
  7     original_language_id   NUMBER REFERENCES language,
  8     rating                 NUMBER
  9  );

Table created.

触发器:不要从触发该行级触发器的表中选择,因为您会遇到 mutating table 错误。对您有好处,您不必这样做 - 改用 :new 伪记录值:

SQL> CREATE OR REPLACE TRIGGER bi_film_desp
  2     BEFORE INSERT
  3     ON film
  4     FOR EACH ROW
  5  DECLARE
  6     l_language           language.name%TYPE;
  7     l_original_language  language.name%TYPE;
  8  BEGIN
  9     SELECT l.name
 10       INTO l_language
 11       FROM language l
 12      WHERE l.language_id = :new.language_id;
 13
 14     SELECT l.name
 15       INTO l_original_language
 16       FROM language l
 17      WHERE l.language_id = :new.original_language_id;
 18
 19     :new.description :=
 20           'Rating: '
 21        || :new.rating
 22        || ', original language: '
 23        || l_original_language
 24        || ', language: '
 25        || l_language;
 26  END;
 27  /

Trigger created.

SQL>

让我们测试一下:

SQL> INSERT INTO film (film_id,
  2                    title,
  3                    language_id,
  4                    original_language_id,
  5                    rating)
  6       VALUES (1,
  7               'Izbavitelj',
  8               1,
  9               2,
 10               7);

1 row created.

结果:

SQL> select title, description, rating from film;

TITLE      DESCRIPTION                                                      RATING
---------- ------------------------------------------------------------ ----------
Izbavitelj Rating: 7, original language: Croatian, language: English             7

SQL>

我觉得不错。

【讨论】:

  • 但我在电影表中的ratingvarchar2(8) 类型。这就是为什么我需要使用COUNT 来显示评级存在多少次。例如评分是“PG”,并且它已经存在于表中 4 次,那么当我添加另一个带有 rating =“PG”的记录时,seq 应该显示 5。这是显示这个的正确方法吗?
猜你喜欢
  • 2014-02-14
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
相关资源
最近更新 更多