如何从加载在 sql/plsql 表中的 csv 文件中获取值

Posted

技术标签:

【中文标题】如何从加载在 sql/plsql 表中的 csv 文件中获取值【英文标题】:How to get the the values from a csv file which is loaded in a table in sql/plsql 【发布时间】:2021-04-08 20:22:39 【问题描述】:

我有一个存储文件 (blob) 的所有相关数据的表。从顶点,我只加载到表 csv 文件中,它接受它。使用我存储在其中的那个 csv 文件,我想从存储在列中的文件中选择内容。

换句话说,我有一个 csv 文件 (employees.csv) 存储在表 (Table A) 列 (File_upload) 中。我想访问 csv 文件的内容而不导出它,而只是从 sql 查询中。

这是一个oracle数据库。该表包括ID(编号)、file_name(varchar2)、file_uploaded(blob)

我尝试了一个示例,但它不起作用,这包括:

  select csv.*
  from tableA d, table(csv_util_pkg.clob_to_csv(d.file_uploaded)) csv
  where d.id= 1;

没有必要修复此代码,非常欢迎替代方案。 提前谢谢!

【问题讨论】:

你看过External Tables吗? 我看了看,但这不是我希望我的系统工作的方式。我想从 apex 和 sqldeveloper 做所有事情。我读到外部表要求您在服务器上创建一个我无权访问的目录。我可能无法完全理解。你能解释一下吗? 是的,您需要访问数据库服务器的文件系统。但是,我认为任何解决方案都需要这个。也许与您的数据库管理员交谈并创建一些 NFS-Share 或类似的。 这和 SQL Developer 有什么关系? 如果文件不能在数据库服务器上,那么它会在哪里? 【参考方案1】:

我认为您的问题在于数据类型。您将文件存储在blob 中,并且您的表函数需要clob

我不知道你的包裹csv_util_pkg,但我认为以下是适合你的解决方案。

设置:

我使用了来自https://github.com/mortenbra/alexandria-plsql-utils的包csv_util_pkg

types.sql csv_util_pkg.pks csv_util_pkg.pkb

创建表

create table tableA (id number(10), 
                     file_name varchar2(255),
                     file_uploaded blob);

上传数据

utl_raw.cast_to_raw() 创建 blob 数据

insert into tableA (id,file_name, file_uploaded) 
values (
1,
'employees.csv',
utl_raw.cast_to_raw(
'"EMPLOYEE_ID","FIRST_NAME","LAST_NAME","EMAIL","PHONE_NUMBER","HIRE_DATE","JOB_ID","SALARY","COMMISSION_PCT","MANAGER_ID","DEPARTMENT_ID"
100,"Steven","King","SKING","515.123.4567",17.06.2003,"AD_PRES",24000,,,90
101,"Neena","Kochhar","NKOCHHAR","515.123.4568",21.09.2005,"AD_VP",17000,,100,90
102,"Lex","De Haan","LDEHAAN","515.123.4569",13.01.2001,"AD_VP",17000,,100,90')
);

创建辅助函数

从https://***.com/a/12854297/12277315获取它

create function clobfromblob(p_blob blob) return clob is
      l_clob         clob;
      l_dest_offsset integer := 1;
      l_src_offsset  integer := 1;
      l_lang_context integer := dbms_lob.default_lang_ctx;
      l_warning      integer;

   begin

      if p_blob is null then
         return null;
      end if;

      dbms_lob.createTemporary(lob_loc => l_clob
                              ,cache   => false);

      dbms_lob.converttoclob(dest_lob     => l_clob
                            ,src_blob     => p_blob
                            ,amount       => dbms_lob.lobmaxsize
                            ,dest_offset  => l_dest_offsset
                            ,src_offset   => l_src_offsset
                            ,blob_csid    => dbms_lob.default_csid
                            ,lang_context => l_lang_context
                            ,warning      => l_warning);

      return l_clob;

   end;
/   

使用辅助函数

select d.file_name,  csv.*
  from tableA d, table(csv_util_pkg.clob_to_csv(clobfromblob(d.file_uploaded))) csv
  where d.id= 1;

Result

注意,我的示例限制为 20 列。在types.sql中查看t_csv_line

【讨论】:

以上是关于如何从加载在 sql/plsql 表中的 csv 文件中获取值的主要内容,如果未能解决你的问题,请参考以下文章

GCP将数据作为字符串从GCS中的CSV文件加载到BigQuery表中

将 csv 文件从云存储加载到大查询

如何在不先定义表中的列的情况下将数据加载到 PostgreSQL 中?

如何防止 Flask-SQLAlchemy 中的 SQL 注入?有没有更好的方法从 CSV 加载数据?

将 CSV 文件中的内容加载到 PostgreSQL 表中

Hive:将hdfs中的gziped CSV作为只读加载到表中