【问题标题】:how to populate database using procedures如何使用过程填充数据库
【发布时间】:2014-11-21 16:12:48
【问题描述】:

我有大约 15 个不同的表,其中填充了不同的数据和不同的实体关系。

我需要创建一个脚本,用这些表的内容填充我的数据库。

脚本完成后,我在 cmd 中运行它,使用 sqlplus 和稍后 START 文件路径

我有两个不同的 sql 文件,一个名为 db_spec.sql,另一个名为 db_body.sql。

在我的 db_body.sql 中,我创建了一个过程来存储两个具有 1:N 关系的表中的数据。

第一张桌子

CREATE TABLE LOCATION (
ID_LOCATION INTEGER NOT NULL,
LOCATION_NAME VARCHAR2 (20) NOT NULL,
POSTCODE INTEGER NOT NULL
);

ALTER TABLE LOCATION
ADD (CONSTRAINT PK_LOCATION PRIMARY KEY (ID_LOCATION));

第二张表

CREATE TABLE ADDRESS (
ID_ADDRESS INTEGER NOT NULL,
STREET VARCHAR2 (20) NOT NULL,
HOUSE_NUMBER INTEGER NOT NULL,
FK_ID_LOCATION INTEGER NOT NULL
);

ALTER TABLE ADDRESS
ADD (CONSTRAINT PK_ADRESS PRIMARY KEY (ID_ADRESS));

ALTER TABLE ADRESS
ADD (CONSTRAINT FK_ADRESS_ID_LOCATION FOREIGN KEY
(FK_ID_LOCATION) REFERENCES LOCATION(ID_LOCATION));

现在我需要使用数据填充它们。比方说

LOCATION_NAME = "伦敦" POSTOCDE = "394505" ...等等

我已经创建了这个脚本,但是当我运行它时,什么都没有显示,所以它显然有一些错误。

db_spec.sql 脚本

CREATE OR REPLACE PACKAGE apartment AS
PROCEDURE fill_location(location_number NUMBER);
PROCEDURE fill_address(number_of_addresses NUMBER);
END apartment;

db_body.sql 脚本

SET SERVEROUTPUT ON
SET LINESIZE 400
SET TIMING ON
CREATE OR REPLACE PACKAGE BODY address AS
PROCEDURE fill_location(location_number NUMBER) IS
    p_location_name VARCHAR2(20);
    p_postcode NUMBER (10,2);
BEGIN
    FOR num IN 1..location_number LOOP
        p_location_name := 'Location';
        p_postcode := dbms_random.value(1000,9600);
        p_postcode := p_postcode ||' '|| TO_CHAR(num);
        INSERT INTO LOCATION (ID_LOCATION, LOCATION, POSTCODE)
        VALUES (num, p_location_name, p_postcode);
        dbms_output.put_line(num);
    END LOOP;
END fill_location;

PROCEDURE fill_address(number_of_adresses NUMBER)IS
    p_street_name VARCHAR(20);
    p_house_number NUMBER (10,2);
    p_id_address NUMBER(10);

    CURSOR data IS
        SELECT ID_LOCATION
        FROM LOCATION;
BEGIN
    FOR num_loop IN data LOOP
        FOR num IN 1..number_of_adresses LOOP
        p_street_name := 'Ulica';
        p_house_number := dbms_random.value(1,99);
        p_street_name := p_street_name ||' '|| TO_CHAR(num);
        SELECT NVL(MAX(p_id_address)+1,1)
        INTO p_id_address
        FROM ADDRESS;
        INSERT INTO ADDRESS (ID_ADDRESS, FK_ID_LOCATION, STREET, HOUSE_NUMBER)
        VALUES (p_id_address, num_loop.ID_LOCATION, p_street_name, p_house_number);
        dbms_output.put_line(num_loop.ID_LOCATION);
        END LOOP;
    END LOOP;           
END fill_address;
END;
SHOW ERRORS;

你们能帮我解决这个问题,这样代码才能正常运行吗?任何意见表示赞赏!

顺便说一句oprema_stanovanja.polni_kraj = address.fill_location

【问题讨论】:

  • 您是否缺少提交?
  • @StevieG 我正在使用 sqlplus 在 cmd 中运行代码。没发生什么事。你能检查一下编辑过的帖子吗?
  • 你说oprema_stanovanja.polni_kraj = address.fill_location。那不应该是 apartment.fill_location 而不是 address.fill_location 吗?如果这是一个错字,您是否在运行该过程后检查了 LOCATION 表是否已填充?你期待什么?
  • 我没看错,只是这里写错了。如何查看表格中的数据?抱歉,这是我第一次使用这个 :(
  • @fox 您需要先修复包,然后再执行它。查看我的回复。

标签: sql database oracle entity-relationship create-table


【解决方案1】:

除非我错过了...COMMIT;
根据您发布的屏幕截图,将/ 添加到您的正文和过程定义的末尾。

【讨论】:

  • 我正在使用 sqlplus 在 cmd 中运行代码。没发生什么事。你能检查一下编辑过的帖子吗?
  • 编译时将show errors放在它们的末尾。
  • 它没有显示任何错误。我不确定 cmd (5,6,7,8) 左侧的那些数字在这种情况下意味着什么。我不确定它是否会通过脚本。
  • 请详细说明为什么COMMIT; 会有所帮助以及应将其插入代码的何处。
  • 这没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。
【解决方案2】:

首先,发布的包无法正确编译。

您需要先解决以下问题:

  1. END LOOP 终止FOR LOOP 语句
  2. END <procedure_name_here> 终止BEGIN 的过程
  3. PL/SQL 变量名需要与实际列名不同,以避免在 INSERT 语句中出现歧义。 [你不能让LOCATION列名和PL/SQL变量同名。 Oracle 无法解析 INSERT 中要使用的位置]

为了让您开始,我已经修复了下面的fill_location 过程。对其他程序进行类似操作。

create or replace package body apartment as
procedure fill_location(location_number number) is
p_location_name varchar2(20);
p_postcode number(10,2);
begin 
    for num in 1.. location_number loop
        p_location_name := 'location';
        p_postcode := dbms_random.value(1000,9600);
        p_location_name := p_location_name ||' '|| to_char(num);
        insert into location (id_location, location_name, postcode)
            values (num, p_location_name, p_postcode);
        dbms_output.put_line(num);
    end loop;
end fill_location;

修复上述错误/建议,直到获得“PL/SQL 编译成功”。如果您得到“编译错误”,请使用“显示错误”来查找并修复任何其他错误。

【讨论】:

  • 谢谢你,我会试试这个,我会在几分钟内返回结果
  • 我尝试在 sqldeveloper 中运行它,这就是我得到的...”第 2 行:SQLPLUS 命令已跳过:设置 LINESIZE 400 PACKAGE BODY oprema_stanovanja 已编译警告:执行已完成,警告已过:00:00: 00.010"
  • @fox 您是否收到“显示错误”的任何错误?请使用固定代码更新您的帖子。 LOCATION 表现在被填充了吗?
  • 你好。我更新了我的代码。实际上,第一部分很容易,因为关系为 1……关系为 N 的第二部分更难解决。仍然得到错误,但它没有显示任何错误......顺便说一句...... cursor 部分是必须的,因为它是老师的指示。你能检查一下代码的第二部分并帮我修复它吗?非常感谢
  • @fox 如果您看到我的示例答案,我已经展示了如何修复 [2]。您需要使用end fill_location; 来结束过程fill_location。您需要使用show errors 命令来实际查看错误。如果这在 SQL 开发人员中不起作用,请使用 SQL*Plus。显示错误后,请阅读、理解它们并修改您的代码。
猜你喜欢
  • 2015-03-05
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
  • 2020-03-14
  • 1970-01-01
  • 1970-01-01
  • 2013-09-27
  • 1970-01-01
相关资源
最近更新 更多