c# - 对于 Snowflake .NET 连接器,我可以在原始(Pascal)外壳中获取列名吗?
问题描述
我正在尝试从雪花数据集自动构建 Excel 文档。我在 C# Core 3.1 中使用 .NET 连接器。但是列名都以大写形式返回,这使得它们难以解释,因为原始列名在数据库中使用 pascal 大小写。是否可以以保留列名的原始大小写的方式设置连接器或查询架构?(我没有重命名数据库中的列的选项)我尝试使用“GetSchemaTable”方法和“GetColumnSchema”方法,如下所示。
const string DATABASE_NAME = "MY_DB";
const string SCHEMA_NAME = "PUBLIC";
const string TABLE_NAME = "VW_FACT";
[Test]
public void GetColumnNamesFromTableUsingColumnSchema()
{
// Arrange...
var script = $"USE DATABASE {DATABASE_NAME}; SELECT * FROM {SCHEMA_NAME}.{TABLE_NAME}";
DbDataReader actualDataset = GetDataSetFromSnowflake(script);
// Act...
IEnumerable<string> columnNames = GetTableNamesUsingColumnSchemaMethod(actualDataset);
// Assert...
Assert.AreEqual(expected: "CanTread", actual: columnNames.ElementAt(0));
// actual = "CANTREAD"
}
[Test]
public void GetColumnNamesFromTableUsingTableSchema()
{
// Arrange...
var script = $"USE DATABASE {DATABASE_NAME}; SELECT * FROM {SCHEMA_NAME}.{TABLE_NAME}";
DbDataReader actualDataset = GetDataSetFromSnowflake(script);
// Act...
IEnumerable<string> columnNames = GetTableNamesUsingTableSchemaMethod(actualDataset);
// Assert...
Assert.AreEqual(expected: "CanTread", actual: columnNames.ElementAt(0));
// actual = "CANTREAD"
}
public DbDataReader GetDataSetFromSnowflake(string script) {
var connection = new SnowflakeDbConnection();
connection.ConnectionString = SNOWFLAKE_CONNECTION_STRING;
connection.Open();
var cmd = connection.CreateCommand();
// Convert script into series of queries... (because .NET connector can't execute scripts yet)
var queries = script.Split(";").ToList();
// Execute any queries prior to final query...
queries.Take(queries.Count - 1).ToList().ForEach(q => {
cmd.CommandText = q;
cmd.ExecuteNonQuery();
});
// Execute final query and return dataset...
cmd.CommandText = queries.Last();
var reader = cmd.ExecuteReader();
connection.Close();
return reader;
}
IEnumerable<string> GetTableNamesUsingTableSchemaMethod(DbDataReader reader)
{
// Use GetSchemaTable...
var tableSchema = reader.GetSchemaTable();
var columnIndexForNameColumn = 2;
for (int rowIndex = 0; rowIndex < tableSchema.Rows.Count; rowIndex++)
{
// Get the column name...
yield return tableSchema.Rows[rowIndex].ItemArray[columnIndexForNameColumn].ToString();
}
}
IEnumerable<string> GetTableNamesUsingColumnSchemaMethod(DbDataReader reader)
{
// Use GetColumnSchema...
var columnCollection = reader.GetColumnSchema();
foreach (var dbCol in columnCollection)
{
// Get the column name...
yield return dbCol.ColumnName;
}
}
解决方案
是否可以以保留列名的原始大小写的方式设置连接器或查询架构?
除非您引用定义对象名称的文字,否则它们始终存储为大写对象并以相同的方式解析。引用文档中的一些相关部分:
不带引号的对象标识符:
不区分大小写。
当标识符未加引号时,它以大写形式存储和解析。
[...]强烈建议您在实施 Snowflake 的早期选择标识符解析方法 [...]
原始大小写不会保留在存储的元数据中,因此除了检查构成查询的原始文本外,没有办法检索它。
我没有重命名数据库中的列的选项
如果区分大小写的命名对您的业务逻辑很重要,您将必须使用带引号的文字重新创建表,这也将要求您始终以相同的形式引用它们:
CREATE TABLE "TableNameWithPreservedCasing" ("ColumnNameToo" string);
SELECT "ColumnNameToo" FROM "TableNameWithPreservedCasing";
推荐阅读
- javascript - 数据表和行详细信息
- php - Nginx 快速 CGI 缓存 ON error_page 404
- php - PHP 错误:致命错误:未捕获的 PDOException:SQLSTATE [42000]:语法错误或访问冲突:1064 您的 SQL 语法有错误;
- dart - 如何将 `ByteData` 实例写入 Dart 中的文件?
- python - 在 SqlAlchemy 中加入时如何将子查询对象转换为 ResultProxy 类?
- c# - IdentityServer3 - 错误 Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException:IDX10503:签名验证失败
- mysql - 从 SQL 列中删除所有字母
- java - 操作栏后退键不起作用
- php - 使用 git 终端时,laravel homestead “找不到驱动程序”
- lua - 使用 lua 文件来要求其他 lua 文件?