如何使用多个值更新列

时间:2018-03-26 17:47:24

标签: sql oracle

我是PLSQL的新手,我想知道如何更新具有多个值的列。例如,假设我有一个名为书籍的桌子,书籍名称和书籍价格,一开始,我只有书“C#”的价格300。更新后,我需要将300和400作为“C#”一书的价格

       Book                          
Book_Name| Price        
---------|---------        
C#       | 300,400           
C++      | 500,600              
Java     | 700,800    

6 个答案:

答案 0 :(得分:1)

创建一个触发器来保存之前的价格。

sql

答案 1 :(得分:1)

我建议另一个 - 标准化 - 选项(我见过你问会是什么?。有很多来源,这就是Wikipedia所说的),一个孩子表格包含这些书籍的所有价格。

虽然您可以将两个(或更多价格)放入一个列中,但请相信 us - 这是一个糟糕而糟糕的选择。

考虑使用这样的东西:

goodList = list(set(badList))

答案 2 :(得分:0)

将同一列中的多个值分隔为某些特定字符绝不是一个好主意。该表应该规范化,或者我们可以像UpdatedPrice一样添加一个新的可空列,并使用它:

ALTER TABLE BOOK
ADD COLUMN UpdatedPrice int
GO

UPDATE BOOK
SET UpdatedPrice = 400
WHERE Book_Name = 'C#'

通过这种方式,您可以同时拥有两种价格。在你的代码中,当UpdatedPrice为null时使用Price,否则使用UpdatedPrice,一切都会好。

答案 3 :(得分:0)

这只是创建存储过程的基本方法,您可以通过在更新后捕获错误代码来改进它。在oracle中拼接字符串的命令是||。

npm ERR! Linux 4.13.0-37-generic 
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "install" "-g" "angular-cli" 
npm ERR! node v4.2.6 
npm ERR! npm v3.5.2 
npm ERR! path /usr/local/bin/ng 
npm ERR! code EEXIST 
npm ERR! Refusing to delete /usr/local/bin/ng: ../lib/node_modules/@angular/cli/bin/ng symlink target is not controlled by npm /usr/local 
npm ERR! File exists: /usr/local/bin/ng 
npm ERR! Move it away, and try again. 
npm ERR! Please include the following file with any support request: 
npm ERR! /home/dosxanzada/WebstormProjects/meanauthapp/npm-debug.log

答案 4 :(得分:0)

正如其他人已经提到的,在一列中共享多个值是不好的做法。如果您确实需要一种产品(书)的多个价格,那么有几种可能的选择: 制作2张桌子: 表1:

create table products
(  id number(5),
   name VARCHAR2(20 CHAR)
);
/
create table prices
(  id number(5),
   value number(6,2),
   product_id number(5),
   FOREIGN KEY (product_id)
        REFERENCES products(id) NOT NULL
)
/
insert into products values(1, 'C#');
insert into products values(1, 'C++');

insert into prices values(1, 300, 1);
insert into prices values(2, 400, 1);
insert into prices values(3, 700, 2);

这样,您可以为一个产品设置多个价格,只需将产品名称保存在一行中,而不是多个。

第二种方法是使用关系表:

create table products
(  id number(5),
   name VARCHAR2(20 CHAR)
);
/
create table prices
(  id number(5),
   value number(6,2),
   product_id number(5)
)
/
create table product_price
(  product_id number(5),
   price_id number(5),
   FOREIGN KEY (product_id)
        REFERENCES products(id) NOT NULL,
   FOREIGN KEY (price_id)
        REFERENCES prices(id) NOT NULL
)
/
insert into products values(1, 'C#');
insert into products values(1, 'C++');

insert into prices values(1, 300);
insert into prices values(2, 400);
insert into prices values(3, 700);

insert into product_price values(1, 1);
insert into product_price values(1, 2);
insert into product_price values(2, 3);

在单个列中存储多个值总是一个坏主意,因为它使得读取数据变得非常困难并带来各种其他问题(如何更新包含的4个值?)。

始终尝试在数据库中仅保存每个值一次(即产品名称“C#”)。并寻找最适合您的解决方案的方式。如果你总是有多个价格只适合一种产品,我会选择第一种方式,有2个表。如果您有多个匹配多个产品的价格,我会选择关系表。

如果您只想在更新列之前保存最后一个价格,请写一个触发器将其保存到日志表中:

create trigger tu_tablename --tu = triggerUpdate
before insert on tablename
for each row
begin
   --writes the values before the insert to the log table
   insert into logTable values (:old.name, :old.price, sysdate);
   --logTable has columns product_name, old_price_value and date_change
end;
/

(请原谅可能的语法错误,将其视为挑战)

答案 5 :(得分:0)

数据库表中的列有一种数据类型,它应该有一个值。虽然如果你真的想这样做,你可以在更新时使用连接,添加到任何已经存在的字符,如此(不需要PL / SQL,只需普通的sql):

UPDATE Book set Price = Price || ', '|| '400' where Book_Name = 'C#' ; 

顺便说一句,如果一本书没有价格,并且你做了这个更新,它最终会看起来像这样:

Book_Name| Price
---------|--------
C#       | ,400

要防止这种情况,请添加一个CASE,以便在其中已有其他值时不包含逗号:

UPDATE Book set Price = 
CASE WHEN Price IS NOT NULL 
THEN Price || ', '|| '400' 
else '400'
end
where Book_Name = 'C#' ; 

然而,这种设计并不是很好。这意味着在字符数据类型的列中,您已经放置了数字,隐藏在内部。

最好有多列:

Book_Name| Price1   | Price2
---------|----------|--------
C#       | 300      |   400
C++      | 500      |   600
Java     | 700      |   800

如果您知道您将拥有的不同价格的数量,则上述情况很好。这只取决于您尝试解决的问题,即业务逻辑。但是,如果您不知道可能的最大价格数量,那么为每本书设置一个二级价格表是有意义的(您需要为每本书设置一个不同的ID,并根据该ID另一个表将有一个所有价格的列表)或者可能改变现有的表格如下:

    Book_Name| Prices   
    ---------|----------
    C#       | 300 
    C#       | 400
    C++      | 500      
    C++      | 600      
    Java     | 700      
    Java     | 800

在这种情况下,您不必更新,而是每次都插入一个新行:

INSERT INTO Book (Book_Name, Price) VALUES ( 'C#', 400) ;
INSERT INTO Book (Book_Name, Price) VALUES ( 'C++', 600) ;
INSERT INTO Book (Book_Name, Price) VALUES ( 'Java', 800) ;