Oracle 将两个字符串合并为一个文本变量PL/sqldeveloper

Oracle 将两个字符串合并为一个文本变量PL/sqldeveloper,oracle,plsql,Oracle,Plsql,使用SQLDeveloper,我试图将firstname和lastname列值合并到PL/SQL中的lv_password文本变量中,但目前为止失败了。代码和错误报告如下。我试着用各种方式来格式化它,在我看来,这一切似乎都是遵循指导原则的,但我显然做了一些不正确的事情 CREATE OR REPLACE PROCEDURE member_ck (lv_cust_id IN bb_shopper.username%TYPE, lv_password IN OUT VARCHAR,

使用SQLDeveloper,我试图将firstname和lastname列值合并到PL/SQL中的lv_password文本变量中,但目前为止失败了。代码和错误报告如下。我试着用各种方式来格式化它,在我看来,这一切似乎都是遵循指导原则的,但我显然做了一些不正确的事情

CREATE OR REPLACE
PROCEDURE member_ck
    (lv_cust_id IN bb_shopper.username%TYPE,
    lv_password IN OUT VARCHAR,
    lv_cookie OUT bb_shopper.cookie%TYPE,
    p_check OUT VARCHAR2)
AS
BEGIN
    SELECT firstname || ' ' || lastname, cookie
    INTO lv_password, lv_cookie
    FROM bb_shopper
    WHERE UPPER(lv_cust_id) = UPPER(username)
    AND lv_password = password;
    DBMS_OUTPUT.PUT_LINE('Name: ' || lv_password || '    Cookie #: ' || lv_cookie);
EXCEPTION
    WHEN NO_DATA_FOUND THEN
    p_check := 'INVALID';    
    DBMS_OUTPUT.PUT_LINE('Incorrect login information');
END member_ck;

/

DECLARE 
    lv_cust_id bb_shopper.username%TYPE := 'rat55';
    lv_password bb_shopper.password%TYPE := 'kile';
    lv_cookie bb_shopper.cookie%TYPE;
    p_check VARCHAR(7); 
BEGIN
    member_ck(lv_cust_id, lv_password, lv_cookie, p_check);
END;    
错误报告

Error report -
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "ORA215.MEMBER_CK", line 8
ORA-06512: at line 7
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    An arithmetic, numeric, string, conversion, or constraint error
           occurred. For example, this error occurs if an attempt is made to
           assign the value NULL to a variable declared NOT NULL, or if an
           attempt is made to assign an integer larger than 99 to a variable
           declared NUMBER(2).
*Action:   Change the data, how it is manipulated, or how it is declared so
           that values do not violate constraints.
  • lv_password
    是第二个参数
  • 您将
    'kile'
    作为其值传递
  • 由于它被声明为
    IN-OUT
    参数,其数据类型为
    VARCHAR2
    (使用
    VARCHAR2
    ,而不是
    VARCHAR
    ),其长度被隐式设置为
    length('kile')=4
  • 当您尝试将firstname和lastname的连接值放入其中时,它太小,无法接受这样一个“long”值
如果你测试它,例如

SELECT substr(firstname || ' ' || lastname, 1, 5)  --> note 5
它也将失败。但是,

SELECT substr(firstname || ' ' || lastname, 1, 4)  --> note 4
我们会成功的


怎么办?不要将其用作输入输出参数;有两个,一进一出。

改变

lv_password IN OUT VARCHAR -- max length dynamically set to length of input


问题是,我隐式地将我的局部变量,特别是lv_密码变量设置为下面匿名代码块中输入字符串的长度,正如Littlefoot指出的那样。解决方案是在长度大得多的匿名代码块中定义变量,以便它们可以接收比输入到过程中更长的字符串。更正代码如下

CREATE OR REPLACE
PROCEDURE member_ck
    (lv_cust_id IN VARCHAR2,
    lv_password IN OUT VARCHAR2,
    lv_cookie OUT NUMBER,
    p_check OUT VARCHAR2)
AS
BEGIN
    SELECT (firstname|| ' ' || lastname), cookie
    INTO lv_password, lv_cookie
    FROM bb_shopper
    WHERE LOWER(lv_cust_id) = LOWER(username)
    AND lv_password = password;
    DBMS_OUTPUT.PUT_LINE('Name: ' || lv_password || '    Cookie #: ' || lv_cookie);
EXCEPTION
    WHEN NO_DATA_FOUND THEN
    p_check := 'INVALID';    
    DBMS_OUTPUT.PUT_LINE('Incorrect login information');
END member_ck;

/

DECLARE 
    lv_cust_id_1 VARCHAR2(255) := 'rat55';
    lv_cust_id_2 VARCHAR2(255) := 'Rat55';
    lv_cust_id_3 VARCHAR2(255) := 'rat';
    lv_password_1 VARCHAR2(255) := 'kile';
    lv_password_2 VARCHAR2(255) := 'steel';
    lv_cookie bb_shopper.cookie%TYPE;
    p_check VARCHAR2(7); 
BEGIN
    member_ck(lv_cust_id_1, lv_password_1, lv_cookie, p_check);
    lv_password_1 := 'kile';
    member_ck(lv_cust_id_2, lv_password_1, lv_cookie, p_check);
    lv_password_1 := 'kile';
    member_ck(lv_cust_id_3, lv_password_1, lv_cookie, p_check);
    member_ck('Kids2', lv_password_2, lv_cookie, p_check);
END; 

不幸的是,在此分配中,我们需要使用in OUT参数。特别是,我们使用中的密码作为输出参数来返回连接的名称字符串。仅当连接到LASTNAME的FIRSTNAME短于作为参数提供的密码时,它才起作用。“作业”是一回事,“让它工作”是另一回事。这是书中的相关文本:“首席开发人员希望最小化参数的数量,以便使用相同的参数接受密码并返回名称值。”老师:“您应该有一个输入参数、一个输入输出参数和两个输出参数。IN-OUT参数将输入密码并输出用户的名字和姓氏(单个文本字符串)。“不,波希米亚人。在Oracle中,您不能指定参数的大小。不幸的是,不能。无效的数据类型。我在主要帖子中找到了一个解释的解决方案。但是CLOB可以,波希米亚人:)这并没有提供问题的答案。若要评论或要求作者澄清,请在他们的帖子下方留下评论。-@umamaomaomao这是怎么回事?”答案?我相信做这个改变会解决问题。如果你想给出答案,那么这个问题就不是你要回答的地方;相反,在问题上添加你自己的答案(是的,回答你自己的问题是件好事),并将答案标记为已接受,以表明这是你的首选解决方案。
CREATE OR REPLACE
PROCEDURE member_ck
    (lv_cust_id IN VARCHAR2,
    lv_password IN OUT VARCHAR2,
    lv_cookie OUT NUMBER,
    p_check OUT VARCHAR2)
AS
BEGIN
    SELECT (firstname|| ' ' || lastname), cookie
    INTO lv_password, lv_cookie
    FROM bb_shopper
    WHERE LOWER(lv_cust_id) = LOWER(username)
    AND lv_password = password;
    DBMS_OUTPUT.PUT_LINE('Name: ' || lv_password || '    Cookie #: ' || lv_cookie);
EXCEPTION
    WHEN NO_DATA_FOUND THEN
    p_check := 'INVALID';    
    DBMS_OUTPUT.PUT_LINE('Incorrect login information');
END member_ck;

/

DECLARE 
    lv_cust_id_1 VARCHAR2(255) := 'rat55';
    lv_cust_id_2 VARCHAR2(255) := 'Rat55';
    lv_cust_id_3 VARCHAR2(255) := 'rat';
    lv_password_1 VARCHAR2(255) := 'kile';
    lv_password_2 VARCHAR2(255) := 'steel';
    lv_cookie bb_shopper.cookie%TYPE;
    p_check VARCHAR2(7); 
BEGIN
    member_ck(lv_cust_id_1, lv_password_1, lv_cookie, p_check);
    lv_password_1 := 'kile';
    member_ck(lv_cust_id_2, lv_password_1, lv_cookie, p_check);
    lv_password_1 := 'kile';
    member_ck(lv_cust_id_3, lv_password_1, lv_cookie, p_check);
    member_ck('Kids2', lv_password_2, lv_cookie, p_check);
END;