ORACLE中select语句中获取字段的数据类型

Posted

技术标签:

【中文标题】ORACLE中select语句中获取字段的数据类型【英文标题】:Get data type of field in select statement in ORACLE 【发布时间】: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' 【参考方案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/NVARCHAR2Type=2 表示NUMBER/FLOATType=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\tcolumn.ColumnName\tcolumn.DataType\tcolumn.DataTypeName\tcolumn.ColumnSize");

catch (Exception exception)

    Console.WriteLine(exception);
    throw;


【讨论】:

以上是关于ORACLE中select语句中获取字段的数据类型的主要内容,如果未能解决你的问题,请参考以下文章

在JSP中获取oracle中的时间戳类型的字段并显示

c#获取oracle数据库表字段名

Oracle:从记录数据类型中选择

oracle数据库如何修改字段的数据类型?

在oracle数据库中,要求两个字段的和要怎么写sql语句

您好,Access数据库中怎么编写SQL语句编写字段类型为char,长度为10