如何使用范围和随机名称的自动增量从其他多个表填充表

时间:2016-12-03 16:18:16

标签: mysql database stored-procedures

我的存储过程遇到了一些问题。

我试图写一个"创建脚本"使用"存储过程"需要输入" n"在0-100000的区间内。

用户输入后,我希望所有信息都进入一个名为" T"的新表。

SELECT * FROM T;

我想要打印:

+----+------------+----------+---------------+---+----+-----+
| Id | First Namne| Last Name| Street Address| No| Zip| City|
+----+------------+----------+---------------+---+----+-----+

街道号码应在1-300范围内。

Zip应该是5个数字,并且不能以0开头。

即使我删除了ID列,每一行也必须是唯一的。

I've made 3 files:
1. Contains 500 unique First Names
2. Contains 500 unique Last Names
3. Contains 335 unique Adresses

我的目标是制作新表" t"接受随机的名字和随机的姓氏。这将需要1次地址300次并使地址不会上升300次然后继续到下一个地址,这样我的所有行都将是唯一的。enter code here

这是我在大脑崩溃前走了多远:

/*
*   Sets database to users
*/
USE users;


/*
*   Removes tables if exists
*/
DROP TABLE IF EXISTS t;
DROP TABLE IF EXISTS first_names;
DROP TABLE IF EXISTS last_names;
DROP TABLE IF EXISTS street_names;


/*
*   Creating new tables
*/
-- Create table t
CREATE TABLE t(
        player_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
        first_name VARCHAR(20) NOT NULL,
        last_name VARCHAR (20) NOT NULL,
        street_name VARCHAR (30) NOT NULL,
        street_number SMALLINT(3) NOT NULL,
        zip MEDIUMINT(5) NOT NULL,
        city VARCHAR(20) NOT NULL
    );


-- Create table first_names
CREATE TABLE first_names (
    first_name_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    first_name VARCHAR(20) NOT NULL
);

Source C:\Database\Inlamning\first_names.txt


-- Create table last_names
CREATE TABLE last_names (
    last_name_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    last_name VARCHAR(20) NOT NULL
);

Source C:\Database\Inlamning\last_names.txt


-- Create table street_names
CREATE TABLE street_names (
    street_name_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    street_name VARCHAR(30) NOT NULL
);

Source C:\Database\Inlamning\street_names.txt


/*
*   Create PRECEDURE "generate_adress"
*/
DROP PROCEDURE IF EXISTS generate_adress;

DELIMITER $$

CREATE PROCEDURE generate_adress(x INT, fn VARCHAR(20), ln VARCHAR(20), sn VARCHAR (30), snno SMALLINT(3), zi MEDIUMINT(5), ci VARCHAR(20))

    BEGIN
    SELECT (SELECT CONCAT("generate_adress", NOW())) as "Start";

    IF (x > 100000) THEN
    SELECT ("Max allowed adresser are 100000, value set to 100000") AS "Number of address:";
    SET x = 100000;
    END IF;

    INSERT INTO "t" (first_name, last_name, street_name, street_number, zip, city)

    END$$

DELIMITER ;



CALL generate_adress(1000);

SELECT * FROM t;

非常感谢帮助!

2 个答案:

答案 0 :(得分:0)

我建议使用以下高级伪代码,然后可以在行sql或SP中使用游标编写代码,和/或使用临时表或使用子查询保存代码等:

1-交叉连接名字和姓氏,这将为您提供250000行所有可能的唯一名称

2-交叉连接街道名称,其中一个表格包含1到300的数字,这将为您提供100500行唯一地址

3-从RAND()(临时表T1)

排序的第一个交叉连接中选择n行

4-从RAND()(临时表T2)

排序的第二个交叉连接中选择n行

5-在行号上加入T1和T2,这将是n个唯一行的结果

邮政编码可以计算为100000 * RAND()

修改

伪代码更详细一点:

set @rownum=0
create table t1 as
(
select @rownum:=@rownum+1 as rownum, x.* 
from (select firstname, lastname from firstnames, lastnames) as x limit 10
) x1

set @rownum=0
create table t2 as
(
select @rownum:=@rownum+1 as rownum, x.* 
from (select number, streetname from streetnames, numbers) as x limit 10
) x1

select * from t1 join t2 on t1.rownum=t2.rownum

答案 1 :(得分:0)

我最终得到了这个解决方案!感谢您收到的帮助!

/*************************************************
*
*   Andreas Ekman Newton Java 2
*
*   CREATE  -- Source C:\Database\Test\CREATE.txt
*   File:   -- Source C:\Database\Inlamning\first_names.txt - 358 Unique ID
*   File:   -- Source C:\Database\Inlamning\last_names.txt - 359 Unique ID
*   File:   -- Source C:\Database\Inlamning\street_names.txt - 335 Unique ID
*   File:   -- Source C:\Database\Inlamning\street_numbers.txt - 300 Uniqe ID
*   File:   -- Source C:\Database\Inlamning\zips.txt - 7 Uniqe ID
*   File:   -- Source C:\Database\Inlamning\cities.txt - 7 Uniqe ID
*
**************************************************/
/*
*   Setting database to "Gamers"
*/
USE Gamers;

/*
*   Creating new tables
*/
-- Create table t
DROP TABLE IF EXISTS t;
CREATE TABLE t(
    player_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    first_name VARCHAR(20) NOT NULL,
    last_name VARCHAR (20) NOT NULL,
    street_name VARCHAR (30) NOT NULL,
    street_number SMALLINT(3) NOT NULL,
    zip MEDIUMINT(5) NOT NULL,
    city VARCHAR(20) NOT NULL
    );


-- Create table first_names
DROP TABLE IF EXISTS first_names;
CREATE TABLE first_names (
    first_name_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    first_name VARCHAR(20) NOT NULL
    );

Source C:\Database\Inlamning\first_names.txt


-- Create table last_names
DROP TABLE IF EXISTS last_names;
CREATE TABLE last_names (
    last_name_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    last_name VARCHAR(20) NOT NULL
    );

Source C:\Database\Inlamning\last_names.txt


-- Create table street_names
DROP TABLE IF EXISTS street_names;
CREATE TABLE street_names (
    street_name_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    street_name VARCHAR(30) NOT NULL
    );

Source C:\Database\Inlamning\street_names.txt


-- Create table street_numbers
DROP TABLE IF EXISTS street_numbers;
CREATE TABLE street_numbers (
    street_number_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    street_number SMALLINT(30) NOT NULL
    );

Source C:\Database\Inlamning\street_numbers.txt


-- Create table zip
DROP TABLE IF EXISTS zips;
CREATE TABLE zips (
    zip_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    zip MEDIUMINT(5) NOT NULL
    );

Source C:\Database\Inlamning\zips.txt


-- Create table citites
DROP TABLE IF EXISTS cities;
CREATE TABLE cities (
    city_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    city VARCHAR(20) NOT NULL
    );

Source C:\Database\Inlamning\cities.txt


/*
*   Create PRECEDURE "generate_adress"
*/
DROP PROCEDURE IF EXISTS generate_adress;

DELIMITER $$

-- CREATE PROCEDURE generate_adress(x INT)
CREATE PROCEDURE generate_adress(x INT)
    BEGIN
        -- Declaring variables
        DECLARE i INT DEFAULT 1;
        DECLARE j INT DEFAULT 1;
        DECLARE k INT DEFAULT 1;
        DECLARE fname VARCHAR(20) DEFAULT 'error';
        DECLARE lname VARCHAR(20) DEFAULT 'error';
        DECLARE stname VARCHAR(30) DEFAULT 'error';
        DECLARE stno SMALLINT(3) DEFAULT '0';
        DECLARE zi MEDIUMINT(5) DEFAULT '0';
        DECLARE ci VARCHAR(20) DEFAULT 'error';

        -- Visualizing the start of generator
        SELECT (SELECT CONCAT("generate_adress", NOW())) as "Start generator!";

        -- Check call ID, max allowed input is 100000
        IF (x > 100000) THEN
            SELECT ("Max allowed addresses are 100000, value set to 100000") AS "Number of adresses";
            SET x = 100000;
        END IF;

        -- Loop for creating inserts to table "t"
        WHILE (i <=x) DO
            -- Setting random value for numbers in the 100's range
            SET @random = FLOOR((RAND()*300 +1));
            -- Setting random value for numbers in the up to 7's range
            SET @randomci = FLOOR((RAND()*7 +1));

            -- Getting random name from first_names table
            SET fname = (SELECT first_name FROM first_names WHERE first_name_id = @random); -- SELECT (fname) as 'first_name';

            -- Getting random last name from last_names table
            SET lname = (SELECT last_name FROM last_names WHERE last_name_id = @random);

            -- Getting street name by ID = k
            SET stname = (SELECT street_name FROM street_names WHERE street_name_id = k);

            -- Getting street name by ID = j
            SET stno = (SELECT street_number FROM street_numbers WHERE street_number_id = j);

            -- Getting a random area code from zips table
            SET zi = (SELECT zip FROM zips WHERE zip_id = @randomci);

            -- Getting a random city from cities table
            SET ci = (SELECT city FROM cities WHERE city_id = @randomci);

            -- Insert data to table called "t"
            INSERT INTO t (first_name, last_name, street_name, street_number, zip, city) VALUES(fname, lname, stname, stno, zi, ci);

            -- Setting the "call generate_adress" counter to tick
            SET i = i+1;

            -- Setting street_name and street_number tick
            SET j = j+1;

            -- Variable counter
            IF (j > 300) THEN
                SET j = 1;
                SET k = k+1;
            END IF;

        -- End of while loop        
        END WHILE;

    -- Visualizing the start of generator
    SELECT (SELECT CONCAT("generate_adress", NOW())) as "Stop generator!";

    -- End of create procedure
    END$$

-- Setting default Delimiter to ;
DELIMITER ;

-- Call command, innout "x" for creating number of x's adresses
CALL generate_adress(1000);

-- View all created addresses
SELECT * FROM t;