简体   繁体   English

触发器中的数字到字符转换错误。 [甲骨文11G]

[英]Number to character conversion error in trigger. [ORACLE 11G ]

I'm trying to make a trigger that returns an error with a specific message when the user tries to insert a new record to Addresses table and provides the wrong post code.我正在尝试创建一个触发器,当用户尝试将新记录插入地址表并提供错误的邮政编码时,该触发器会返回带有特定消息的错误。 Two IF statements check if the number of characters in the given post-code is right (it should be 6: 2 numbers, 1 dash and 3 numbers).两个 IF 语句检查给定邮政编码中的字符数是否正确(应该是 6:2 个数字、1 个破折号和 3 个数字)。 Another IF statement checks if the position of the dash is 3. When I try to insert a post-code with too few characters (for example '12932') it works fine and returns the right message.另一个 IF 语句检查破折号的 position 是否为 3。当我尝试插入字符太少的邮政编码(例如“12932”)时,它工作正常并返回正确的消息。 The problem begins when I provide the post-code in which the dash position is incorrect (for example '1-9000').当我提供破折号 position 不正确的邮政编码(例如“1-9000”)时,问题就开始了。 In such case it returns an error (PL/SQL: numeric or value error: character to number conversion error, line 15).在这种情况下,它返回一个错误(PL/SQL:数字或值错误:字符到数字的转换错误,第 15 行)。 What could be the reason?可能是什么原因? Because personally I can't find any char to number conversions.因为我个人找不到任何字符到数字的转换。 Thanks.谢谢。

Code:代码:

CREATE OR REPLACE TRIGGER post_code_trigger
BEFORE INSERT OR UPDATE ON Addresses
FOR EACH ROW

DECLARE
code_length NUMBER; 
index_of_dash NUMBER;
code_tmp VARCHAR(6);

BEGIN
code_tmp := :NEW.Post_code;
code_length := LENGTH(code_tmp);
index_of_dash := INSTR(code_tmp, '-');

IF(code_length <> 6) THEN
    RAISE_APPLICATION_ERROR(-20000, 'Post code contains the wrong number of characters.');
ELSE
    IF (index_of_dash <> 3) THEN
        RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain '-' character or it is in the wrong posiition. Sample post code "26-500" ');
    END IF;
    
END IF;

END;
/


INSERT INTO Addresses (address_ID, city, post_code, province, street_name, house_number) VALUES (2, 'Warsaw','1-9000','mazowieckie','Sylvester Stallone Street', 67);

In the body of the code, indekx_of_dash does not match index_of_dash in the declaration.在代码主体中, index_of_dash与声明中的indekx_of_dash不匹配。 Once you fix that typo, it works.一旦你修正了那个错字,它就可以工作了。

It can be simplified to:可以简化为:

CREATE OR REPLACE TRIGGER post_code_trigger
BEFORE INSERT OR UPDATE ON Addresses
FOR EACH ROW
DECLARE
BEGIN
  IF LENGTH(:NEW.Post_code) <> 6 THEN
    RAISE_APPLICATION_ERROR(-20000, 'Post code contains the wrong number of characters.');
  ELSIF INSTR(:NEW.Post_code, '-') <> 3 THEN
      RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain "-" character or it is in the wrong posiition. Sample post code "26-500" ');
  END IF;
END;
/

But you probably don't want to use a trigger and just want a CHECK constraint.但是您可能不想使用触发器,而只想使用CHECK约束。

ALTER TABLE addresses ADD CONSTRAINT addresses_postcode_format
  CHECK (post_code LIKE '??-???');

db<>fiddle here db<> 在这里摆弄

Ok, I found a solution.好的,我找到了解决方案。 Firstly I simplified my code according to the MT0's answer.首先,我根据 MT0 的回答简化了我的代码。 Then I deleted the '-' part from the error message.然后我从错误消息中删除了“-”部分。 Now everything works as it should.现在一切正常。 Thank you.谢谢你。

IF INSTR(:NEW.Post_code, '-') <> 3 THEN
        RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain a dash character or it is in the wrong posiition. Sample post code "26-500" ');

instead of代替

ELSIF INSTR(:NEW.Post_code, '-') <> 3 THEN
      RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain '-' character or it is in the wrong posiition. Sample post code "26-500" ');

When you originally posted your question you had this line:当您最初发布您的问题时,您有这行:

RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain "-" character or it is in the wrong posiition. Sample post code "26-500" ');

Your real code actually has (but with Polish text):您的真实代码实际上具有(但带有波兰语文本):

RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain '-' character or it is in the wrong posiition. Sample post code "26-500" ');

The problem then is the '-' in the middle of that.那么问题是中间的'-' The single quotes around the dash end one string, and start another;破折号周围的单引号结束一个字符串,并开始另一个; and the dash is now outside the string literal(s), so Oracle interprets it as a minus sign.并且破折号现在位于字符串文字之外,因此 Oracle 将其解释为减号。 That causes it to implicitly convert the two shorter string literals either side to numbers, so they can be subtracted from each other.这会导致它隐式地将两侧的两个较短的字符串文字转换为数字,因此可以将它们相互减去。 So you're really doing:所以你真的在做:

to_number('Post code doesnt contain ')
-
to_number(' character or it is in the wrong posiition. Sample post code "26-500" ')

The error is occurring when it tries to convert those strings, because they clearly do not represent numbers.当它尝试转换这些字符串时会发生错误,因为它们显然不代表数字。

With the dash enclosed in double-quotes instead the whole thing is one string literal again, so there is no confusion or attempt to perform a calculation.用双引号括起来的破折号,整个事情又是一个字符串文字,所以没有混淆或尝试执行计算。


Incidentally, you seem to have avoided an issue with quotes with doesnt instead of doesn't , though presumably only in the translated version.顺便说一句,您似乎避免了使用doesnt而不是doesn't n't 的引号问题,尽管可能仅在翻译版本中。 But if you wanted to use single quotes within a string, you can either escape them:但是如果你想在字符串中使用单引号,你可以转义它们:

'Post code doesn''t contain ''-'' character or it is in the wrong position. Sample post code ''26-500'''

or use the alternative quoting mechanism :或使用替代报价机制

q'[Post code doesn't contain '-' character or it is in the wrong position. Sample post code '26-500']'

db<>fiddle demo db<>小提琴演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM