【问题标题】:Get data type of field in select statement in ORACLEORACLE中select语句中获取字段的数据类型
【发布时间】:2014-05-22 15:06:29
【问题描述】:

我可以使用 select 语句获取我选择的每一列的数据类型而不是值吗?

例如:

SELECT a.name, a.surname, b.ordernum 
FROM customer a
JOIN orders b
ON a.id = b.id

结果应该是这样的

name    | NVARCHAR(100)
surname | NVARCHAR(100)
ordernum| INTEGER

也可以像这样排成一行,不重要:

name           |   surname     |  ordernum
NVARCHAR(100)  | NVARCHAR(100) |   INTEGER

谢谢

【问题讨论】:

  • 使用'desc table_name'

标签: sql oracle function types


【解决方案1】:

您可以在数据库中查询all_tab_columns视图。

SELECT  table_name, column_name, data_type, data_length FROM all_tab_columns where table_name = 'CUSTOMER'

【讨论】:

  • 是的,但这不适用于这样的查询:SELECT a.name, a.surname, TO_CHAR(b.ordernum) as ordernum_char。为此,您必须使用包 DBMS_SQL 并使用显式游标。
  • @WernfriedDomscheit 欢迎提供具体示例。
【解决方案2】:

我也遇到了同样的情况。作为一种解决方法,我刚刚创建了一个view(如果您有权限)并对其进行了描述并稍后将其删除。 :)

【讨论】:

  • #NiceIdea 这正是我所需要的
【解决方案3】:

我发现使用DUMP() 的方法不是很直观

SELECT DUMP(A.NAME), 
       DUMP(A.surname), 
       DUMP(B.ordernum) 
FROM   customer A 
       JOIN orders B 
         ON A.id = B.id

它会返回如下内容:

'Typ=1 Len=2: 0,48' 对应每一列。

Type=1 表示VARCHAR2/NVARCHAR2
Type=2 表示NUMBER/FLOAT
Type=12 表示DATE

您可以参考这个 oracle 文档以获取信息Datatype Code
或者这是一个简单的映射Oracle Type Code Mappings

【讨论】:

    【解决方案4】:

    我通常创建一个视图并使用DESC 命令:

    CREATE VIEW tmp_view AS 
    SELECT 
          a.name
        , a.surname
        , b.ordernum 
    FROM customer a
      JOIN orders b
        ON a.id = b.id
    

    然后,DESC 命令将显示每个字段的类型。

    DESC tmp_view

    【讨论】:

      【解决方案5】:

      如果您没有在 Oracle 中创建视图的权限,请围绕它“破解”以使用 MS Access :-(

      在 MS Access 中,使用您的 sql 创建一个传递查询(但添加 where 子句以仅选择 1 条记录),从视图创建一个选择查询(非常重要),选择所有 *,然后从选择查询。当它运行时,它将创建一个包含一条记录的表,所有数据类型都应该“匹配”oracle。 即 Passthrough --> Select --> MakeTable --> Table

      我相信还有其他更好的方法,但如果您的工具和权限有限,这将起作用。

      【讨论】:

        【解决方案6】:

        另外,如果您有 Toad for Oracle,您可以突出显示该语句并按 CTRL + F9,您会很好地查看列及其数据类型。

        【讨论】:

          【解决方案7】:
          you can use the DBMS_SQL.DESCRIBE_COLUMNS2
          
              SET SERVEROUTPUT ON;
          DECLARE
              STMT CLOB;
              CUR NUMBER;
              COLCNT NUMBER;
              IDX NUMBER;
              COLDESC DBMS_SQL.DESC_TAB2;
          BEGIN
              CUR := DBMS_SQL.OPEN_CURSOR;
              STMT := 'SELECT  object_name , to_char(object_id), created FROM    DBA_OBJECTS where rownum<10';
          
              SYS.DBMS_SQL.PARSE(CUR, STMT, DBMS_SQL.NATIVE);
              DBMS_SQL.DESCRIBE_COLUMNS2(CUR, COLCNT, COLDESC);
              DBMS_OUTPUT.PUT_LINE('Statement: ' || STMT);
              FOR IDX IN 1 .. COLCNT
              LOOP
                  CASE COLDESC(IDX).col_type
                  WHEN 2 THEN
                      DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': NUMBER');
                  WHEN 12 THEN
                      DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': DATE');
                  WHEN 180 THEN
                      DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': TIMESTAMP');
                  WHEN 1 THEN
                      DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': VARCHAR'||':'|| COLDESC(IDX).col_max_len);
                  WHEN 9 THEN
                      DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': VARCHAR2');
                  -- Insert more cases if you need them
                  ELSE
                      DBMS_OUTPUT.PUT_LINE('#' || TO_CHAR(IDX) || ': OTHERS (' || TO_CHAR(COLDESC(IDX).col_type) || ')');
                  END CASE;
              END LOOP;
              SYS.DBMS_SQL.CLOSE_CURSOR(CUR);
          EXCEPTION 
              WHEN OTHERS THEN
                  DBMS_OUTPUT.PUT_LINE(SQLERRM(SQLCODE()) || ': ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
                  SYS.DBMS_SQL.CLOSE_CURSOR(CUR);
          END;
          /
          
          
          full example in the below url
          
          https://www.ibm.com/support/knowledgecenter/sk/SSEPGG_9.7.0/com.ibm.db2.luw.sql.rtn.doc/doc/r0055146.html
          

          【讨论】:

          • 这看起来像是 DB2 的答案,问题是关于 Oracle 的。
          【解决方案8】:

          字段数据类型数据可从ODP.Net 中的客户端代码获得。期望 Oracle 其他库也必须支持模式信息。在 C# 脚本中很简单,您只需要一个连接字符串和 SELECT 语句。仅询问架构数据。到目前为止,此解决方案不需要我的测试所需的额外 CREATE VIEW 权限。解析选择表达式的类型。 Con 确实为数据库增加了额外的往返行程。

          示例使用的是c# 10,可能需要降级语法。 Constants.ContainerConnectionString 是一个连接字符串,Constants.DvcrSyntax 可以是任何选择语句。

          using System.Data;
          using Oracle.ManagedDataAccess.Client;
          using OracleSchemaSample;
          
          var connectionBuilder =
              new OracleConnectionStringBuilder(Constants.ContainerConnectionString)
              {
                  ConnectionTimeout = 30,
                  Enlist = "false",
                  PersistSecurityInfo = true
              };
          await using var connection = new OracleConnection(connectionBuilder.ConnectionString);
          await using var command = new OracleCommand(Constants.DvcrSyntax, connection);
          var cts = new CancellationTokenSource();
          try
          {
              await connection.OpenAsync(cts.Token);
              connection.ModuleName = "MyUnqueApplicatonName";
              connection.ClientId = Guid.NewGuid().ToString(); // Tracing identity
              await using var schemaReader = await command.ExecuteReaderAsync(CommandBehavior.SchemaOnly, cts.Token);
              var columnSchema = await schemaReader.GetColumnSchemaAsync(cts.Token);
              foreach (var column in columnSchema)
                  Console.WriteLine(
                      $"{column.ColumnOrdinal}\t{column.ColumnName}\t{column.DataType}\t{column.DataTypeName}\t{column.ColumnSize}");
          }
          catch (Exception exception)
          {
              Console.WriteLine(exception);
              throw;
          }
          
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-06-24
            • 1970-01-01
            • 1970-01-01
            • 2011-01-19
            • 2017-04-29
            相关资源
            最近更新 更多