无法选择 *(ORA-00932:不一致的数据类型:预期的 CHAR 得到了 ADT)

Posted

技术标签:

【中文标题】无法选择 *(ORA-00932:不一致的数据类型:预期的 CHAR 得到了 ADT)【英文标题】:Can't SELECT * (ORA-00932: inconsistent datatypes: expected CHAR got ADT) 【发布时间】:2020-12-13 04:35:27 【问题描述】:

更新更新: 我可以通过定义列名进行查询...所以问题出在 query SELECT * 但我有接近 100 列我的桌子..我不想把它们全部硬核并维护那个列表..为什么我不能使用SELECT * ??


我只是想创建一个按钮;他们用户可以选择三个表之一导出为 .csv 文件的前端。单击选项 -> 选择通过table:which; 传递回我的 php,然后将在 oracle 数据库中查询特定表并在浏览器中下载。以下是我返回错误的尝试。


jQuery前端调用(导出按钮点击):

$('#export' + '.' + crnt).click(function()
      let which = crnt;
      window.location.href = "export?table="+which;
);

PHP 通过苗条路线:

<?php
    
$app->post('/export', function ($request, $response, $args)     

    $which = $_POST['table'];
    
    $config = parse_ini_file(__DIR__ . '/../../xx/xx.ini');
    $dbuser = $config['dbuser'];
    $dbpass = $config['dbpass'];
    $dbhost = $config['dbhost'];
    $dbname = $config['dbname'];
    $constr = $dbhost.'/'.$dbname;
    $conn = oci_pconnect($dbuser, $dbpass, $constr, 'XXX');

    if ($which == 'table_1')
        $sql = 'SELECT * FROM app.table_1';
        $columnsql = 'SELECT column_name FROM app.table_1';
     else if ($which == 'table_2')
        $sql = 'SELECT * FROM app.table_2';
        $columnsql = 'SELECT column_name FROM app.table_2';
     else if ($which == 'table_3')
        $sql = 'SELECT * FROM app.table_3';
        $columnsql = 'SELECT column_name FROM app.table_3';
    

    $stmt = oci_parse($conn, $sql); 
    $columnstmt = oci_parse($conn, $columnsql); 
    oci_execute($stmt);
    oci_execute($columnstmt);

    $columnnames = oci_fetch_array($columnstmt, OCI_ASSOC);
    $output = fopen("php://output", "w");
    fputcsv($output, $columnnames);

    while ($row = oci_fetch_array($stmt, OCI_ASSOC)) 
        fputcsv($output, $row);
    

    fclose($output);

    header("Content-Type: text/csv; charset=utf-8");
    header("Content-Disposition: attachment; filename=$which.csv");
    
    if (!@oci_execute($stmt)) 
       $error = oci_error($stmt);
       throw new Exception($error['message']);
    

    if (!@oci_execute($columnstmt)) 
       $error = oci_error($columnstmt);
       throw new Exception($error['message']);
    

);

错误 500: 以上在我的开发工具网络控制台 -> 预览响应选项卡中返回以下错误:


更新:

我现在已将所有 post 实例更新为 -> get 修复了 post method not allowed 消息,但我仍然收到 ORA inconsistent datatypes error ...这是与此有关吗我在 php 中的headers?我把它们包括在哪里?我还需要在ajax 调用中指定数据类型吗?如何处理潜在的*ADT* 数据类型?

【问题讨论】:

当您在浏览器中导航到一个 url 时,您将使用 GET 请求。您要么需要更改路线允许的方法,例如$app->get,或者使用 Postman 之类的东西来创建一个 POST 请求。 是的,那是因为它是一个 POST 变量,但您现在已将请求更改为 GET 请求。对于测试,您可以更改 $which = $_POST['table'];到 $_GET['table'] 甚至 $_REQUEST['table'] 我的意思是我看到了一些问题示例,如果表中的列具有对象类型,则可能会出现问题。例如bugs.php.net/bug.php?id=74647 回复:“具有列数据类型的表的定义”。他的意思是更新您的问题以显示定义表格的格式 DDL。或者 sqlplus 命令的输出 'describe 。如docs.oracle.com/cd/E11882_01/server.112/e16604/… 所述 如果要导出CSV中的几何列,需要使用SQL函数将其转换为文本。如果您不想导出它,那么您应该提供要导出的列的列表。在这两种情况下,您都需要删除 * 并明确给出列。 【参考方案1】:

您可以通过获取列名并将它们全部转换为创建的查询中的文本字符串来动态创建查询(甚至可以将文本转换为文本)。 https://docs.microsoft.com/en-us/sql/t-sql/spatial-geometry/tostring-geometry-data-type?view=sql-server-ver15

您是否要将列名放在第一个 CSV 行中?

【讨论】:

'你要把列名放在第一个 CSV 行吗?'是的。【参考方案2】:

提取列的请求很奇怪。不就是这样吗?

select column_name from all_tab_columns where table_name = 'table_1';

您使用 OCI_ASSOC。您可以使用类似的功能保存请求

while ($row = oci_fetch_array($stmt, OCI_ASSOC)) 
        write_head_column($output, $row);
        fputcsv($output, $row);


function write_head_column(&$output, $row)
  static $is_done;
  if(empty($is_done))
    $head = key($row);
    fputcsv($output, $head);
    $is_done = true;
  

【讨论】:

【参考方案3】:

看起来你们中有一个列是对象,比如SDO_GEOMETRY,这种列不能通过* 选择 你应该使用类似的东西

SELECT c.shape.Get_Dims()
FROM cola_markets c WHERE c.name = 'cola_b';

@见https://docs.oracle.com/database/121/SPATL/sdo_geometry-methods.htm#SPATL498

【讨论】:

以上是关于无法选择 *(ORA-00932:不一致的数据类型:预期的 CHAR 得到了 ADT)的主要内容,如果未能解决你的问题,请参考以下文章

ORA-00932不一致的数据类型预期 char 得到数字

ORA-00932: 不一致的数据类型: 预期 - 得到 - ORA-06512:

ORA-00932: 不一致的数据类型: 预期 - 得到 CLOB

如何修复 PL/SQL:ORA-00932:不一致的数据类型:预期的 CLOB 得到了 -

ora-00932 不一致的数据类型预期数字得到 char plsql

ORA-00932 数据类型不一致: 应为 -, 但却获得 -