【问题标题】:Can you use Object Types in Procedures in Oracle PL/SQL?您可以在 Oracle PL/SQL 的过程中使用对象类型吗?
【发布时间】:2021-02-04 12:44:30
【问题描述】:

各位程序员大家好。我目前正在为我的学习计划开发一个网上商店数据库。目前,我正在尝试创建一个程序,在创建客户时在订单表中创建订单。我也在考虑将其放入构造函数中,但由于我想在订单达到特定状态时使用此功能两次,并且在创建后我想将此功能捆绑在一个过程中。我已经花了将近 8 个小时的时间来研究和测试这个问题,但是由于 oracle db 对我的代码的反馈是 0 到什么都没有,我无法弄清楚出了什么问题。当我创建程序时,它没有被标记为有效,当我单击程序时,我什至看不到参数选项卡中的参数。我希望代码格式化有效这是我的第一篇文章..

这是订单和客户的类型,它们相互持有 REF

CREATE TYPE ORDER_TYPE AS OBJECT(
Order_Id NUMBER,
Date_of_Creation DATE,
Items ITEM_LIST,
Status REF STATUS_TYPE,
Customer REF CUSTOMER_TYPE
);

CREATE TYPE CUSTOMER_TYPE AS OBJECT(
Customer_Id NUMBER,
Email VARCHAR2(254),
User_Name VARCHAR2(50),
Password VARCHAR2(20),
First_Name VARCHAR2(50),
Last_Name VARCHAR2(50),
Address ADDRESS_TYPE,
Shopping_Cart REF ORDER_TYPE
);

CREATE TABLE Orders OF ORDER_TYPE(Status SCOPE IS Order_Status NOT NULL,        Customer NOT NULL)
NESTED TABLE Items STORE AS ORDER_ITEMS_NT_TAB;
ALTER TABLE Orders ADD CONSTRAINT PK_Orders PRIMARY KEY(Order_Id);
CREATE TABLE Customers OF CUSTOMER_TYPE(Customer_Id PRIMARY KEY,
                                    Email NOT NULL,
                                    User_Name NOT NULL,
                                    Password NOT NULL,
                                    First_Name NOT NULL,
                                    Last_Name NOT NULL,
                                    Address NOT NULL);

这是程序代码。输入应该是客户创建或更新的。然后我想插入一个新订单,我仍然需要将 id 字段更改为 guid 或 uuid,因此每个订单都是唯一的,但出于测试目的,我只使用了 1。项目列表首先应该是空的,并且订单的状态应该是状态 1,代表“Shopping_Cart”,这意味着订单仍在创建中,稍后应该在浏览器中显示为购物车。插入后,我想用返回语句返回插入的行,因此我无法更新客户并将他的购物车的参考设置为新插入的订单。我无法弄清楚我仍在努力解决什么问题,但我会很感激任何帮助。

CREATE PROCEDURE create_customer_order(customer IN CUSTOMER_TYPE) AS
DECLARE 
    shopping_c NUMBER;
BEGIN
    INSERT INTO ORDERS 
    VALUES(1,CURRENT_DATE ,NEW ITEM_LIST(),(SELECT REF(os) FROM ORDER_STATUS os WHERE VALUE(os).STATUS_ID = 1),REF(customer)) 
    RETURNING Order_Id INTO shopping_c;
    
    UPDATE CUSTOMERS c  
    SET c.SHOPPING_CART = (SELECT REF(o) FROM ORDERS o WHERE o.ORDER_ID = shopping_c) 
    WHERE c.CUSTOMER_ID = customer.CUSTOMER_ID;
END;

如果有不清楚的地方,请随时提出问题。干杯!

【问题讨论】:

    标签: oracle plsql procedure object-type


    【解决方案1】:

    我将提供一个工作示例。 但首先,您没有提供所有类型。所以我假设他们。 我看到你有相互引用的类型。这基本上不是一个好主意。 对于存储数据,您可以使用对象类型,但也可以使用普通数据类型,例如 number/varchar2。您将需要表订单/订单项/客户。如果您想更改 customer_type 并且您的表已经填充了数据,那么更改类型很困难(如何处理旧数据?)。

    但回到你的问题,这里有一个工作示例。

    drop type customer_type force;
    drop type order_type force;
    drop type address_Type force;
    drop type status_type force;
    drop type item_list force;
    
    create type STATUS_TYPE as object (
    status number
    );
    
    create type ADDRESS_TYPE as object (
    street varchar2(100)
    );
    
    create type ITEM_LIST as object (
    itemname varchar2(100)
    );
    
    CREATE TYPE ORDER_TYPE AS OBJECT(
    Order_Id NUMBER,
    Date_of_Creation DATE,
    Items ITEM_LIST,
    Status REF STATUS_TYPE,
    Customer REF CUSTOMER_TYPE
    );
    
    CREATE TYPE CUSTOMER_TYPE AS OBJECT(
    Customer_Id NUMBER,
    Email VARCHAR2(254),
    User_Name VARCHAR2(50),
    Password VARCHAR2(20),
    First_Name VARCHAR2(50),
    Last_Name VARCHAR2(50),
    Address ADDRESS_TYPE,
    Shopping_Cart REF ORDER_TYPE
    );
    
    alter type order_type compile;
    
    drop table orders;
    
    CREATE TABLE Orders (id number, Status status_type ,  Customer CUSTOMER_TYPE);
    
    CREATE OR REPLACE PROCEDURE create_customer_order(p_customer IN CUSTOMER_TYPE) AS
        shopping_c NUMBER;
    BEGIN
      dbms_output.enable(null);
        INSERT INTO ORDERS (id, status, customer)
        VALUES (1, null, p_customer)
        RETURNING id INTO shopping_c;
    
        commit;
      dbms_output.put_line('id='||shopping_c);
    END;
    /
    
    --Test
    declare
      l_customer customer_type;
    begin
      l_customer := customer_type (Customer_Id => 1
                                 , email=>'a@b.org'
                                 , user_name=>'test'
                                 , password=>'DoyouReallyWantThis'
                                 , first_name=>'first'
                                 , last_name =>'last'
                                 , address=>null --for simplicity
                                 , shopping_cart=>null --for simplicity
                                 );
      create_customer_order(p_customer => l_customer);
    
    end;
    /
    

    【讨论】:

      【解决方案2】:

      感谢您的回答.. 它对我不起作用,您也错过了程序中的更新部分,但仍然感谢您的努力。我设法通过逐步运行每个代码段并观察它是否失败来使程序正常工作。对我来说感觉就像 javascript 哈哈。我发现由于某种原因我不能解释你不能在声明语句下声明变量,你不能使用定义的对象类型作为参数。我在文档中找不到任何关于它的信息。对于仍然对我如何解决问题感兴趣的每个人,这是代码。

      CREATE OR REPLACE PROCEDURE create_customer_order(p_customer_id IN NUMBER) 
      AS
      BEGIN
              INSERT INTO ORDERS 
              VALUES(1, CURRENT_DATE, NEW ITEM_LIST(),(SELECT REF(os) FROM ORDER_STATUS os WHERE os.STATUS_ID = 1),(SELECT REF(c) FROM CUSTOMERS c WHERE c.CUSTOMER_ID = p_customer_id));
              
              UPDATE CUSTOMERS c  
              SET c.SHOPPING_CART = (SELECT REF(o) FROM ORDERS o WHERE DEREF(o.Customer).Customer_Id = p_customer_id AND DEREF(o.STATUS).Status_Id = 1 ) 
              WHERE c.CUSTOMER_ID = p_customer_id;
      END;
      

      【讨论】:

        猜你喜欢
        • 2020-02-27
        • 2010-11-07
        • 2021-05-06
        • 1970-01-01
        • 1970-01-01
        • 2012-03-04
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        相关资源
        最近更新 更多