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/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\tcolumn.ColumnName\tcolumn.DataType\tcolumn.DataTypeName\tcolumn.ColumnSize");
catch (Exception exception)
Console.WriteLine(exception);
throw;
【讨论】:
以上是关于ORACLE中select语句中获取字段的数据类型的主要内容,如果未能解决你的问题,请参考以下文章