【问题标题】:load data in mysql and avoid duplication of records在mysql中加载数据并避免重复记录
【发布时间】:2012-02-17 01:41:40
【问题描述】:

我在我的 perl 文件中运行以下代码:

LOAD DATA INFILE 'file_name'
INTO TABLE tbl_name
FIELDS TERMINATED BY ','
(columns..., @var, morecolumns...)
SET datecolumn = str_to_date(@var, '%d/%m/%Y');

我有两个问题:

  1. 当我运行 perl 文件时,我收到以下错误。这是否意味着我必须在数据库中的表中添加一个字段“var”?

    全局符号“@var”在 process.pl 第 37 行需要明确的包名称。 由于编译错误,process.pl 的执行被中止。

  2. 如果出于任何原因我必须重新加载 .csv 文件中的数据并再次运行此命令,它会将新记录添加为重复项。如何编辑上述代码以避免重复记录?

更新了 Perl 的相关代码:

 my $sql = "LOAD DATA LOCAL INFILE '$fname' INTO TABLE $tname FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n' (trade_dt,t_id,....open_int);";
 print $sql,"\n"; #date is going in as '0000-00-00'
  $dbh->do($sql) or die $dbh->errstr;

这是它在 mySQL 中显示的内容

mysql> select max(trade_dt) from test;
+---------------+
| max(trade_dt) |
+---------------+
| 0000-00-00    |
+---------------+
1 row in set (0.04 sec)

我的理解是我需要添加SET trade_dt=str_to_date() 才能将日期作为yyyy-mm-dd 添加到我的数据库中。在我上传到数据库的 .csv 文件中,日期格式为dd/mm/yyyy

另外,如果有帮助,这就是在 mySQL 表中声明 trade_dt 的方式,测试:

trade_dt date NOT NULL

【问题讨论】:

    标签: mysql perl date


    【解决方案1】:

    第一个问题中的错误信息意味着 Perl 正在将此字符串中的 @var 解释为全局 Perl 数组名称 @var,而不是 SQL 变量。这也意味着您在程序顶部说use strict,这很棒!

    解决方法是转义字符串中的特殊 @ 字符:

    (columns..., \@var, morecolumns...)
    SET datecolumn = str_to_date(\@var, '%d/%m/%Y');
    

    【讨论】:

    • 我声明了my @var;,然后用\转义了@。它没有给我任何错误,但它将日期插入为0000-00-00
    • @user1155299 你到底为什么要声明变量转义它?这是没有意义的。你必须要么做要么,这取决于@var 是 perl 还是 mysql 变量。
    • 我相信它是一个mysql变量。我是新手,所以我犯了一个错误。非常感谢您对如何修复它的建议。
    • @user1155299 如果他们不知道它是如何损坏的,没有人可以告诉您如何修复它。您需要出示您的代码。
    • 好的,让我发布我的相关 Perl 代码。看来我不需要@var。
    【解决方案2】:

    对于第二个问题,将数据加载到临时表中,然后使用游标读取临时表上的行并将它们插入到真实表中,避免使用一些逻辑代码重复(where 条件,如果存在结构控制等) .

    【讨论】:

      【解决方案3】:

      你能用“REPLACE”代替“INSERT”吗?如果没有,那么您可以在插入之前清空表格吗?

      我必须在我使用的 java 程序中的主 INSERT 之前清空一个表,因为我不关心旧数据...

      【讨论】:

        【解决方案4】:

        错误Global symbol @var.. 来自perl,意味着您的变量@var 未在当前范围内声明。假设它被正确使用,您可以使用my @var 声明它。如果它是一些非 perl 变量,则需要单引号字符串以避免变量插值。很难说你应该做什么,因为你没有显示你的代码。例如:

        my $query = q#LOAD DATA INFILE 'file_name'
        INTO TABLE tbl_name
        FIELDS TERMINATED BY ','
        (columns..., @var, morecolumns...)
        SET datecolumn = str_to_date(@var, '%d/%m/%Y');#;
        

        请注意,q() 将根据您的需要采用替代分隔符,例如 #,并将防止字符串中的变量插值。

        如果它是一个 perl 变量,您可能应该使用 placeholdersDBI 模块(或类似模块)来增加安全性。 @var 数组如果在双引号字符串中,将被扩展并填充空格(如果 $" 设置为默认值),这可能不是您想要的。例如:

        my @var = ("foo", "bar", "baz");
        print "@var";
        

        将打印foo bar baz

        【讨论】:

        • 我按照你的建议声明了它,现在没有错误,但它插入了0000-00-00
        • @user1155299 好吧,它是一个 perl 变量吗?如果不是,那么你当然不应该声明它,因为它会在你的代码中插入一个空白和错误的值。
        • 好吧,我基本上是在遵循 mySQL 网站上的这个例子:forums.mysql.com/read.php?10,136269,136273#msg-136273,似乎我在将它声明为 Perl 变量时犯了一个错误。什么是正确的方法。我的 .csv 中的日期为 22/01/2012,我希望它输入为 2012-01-22。
        • @user1155299 好吧,如果你不知道@var 来自哪里,那么我不能告诉你。也许你应该展示更多你的 perl 代码。
        • 任何想法 - 我想要的只是作为 %Y-%m-%d 插入数据库的日期
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多