从查询中获取表架构

2023-11-24

As per MSDN, SqlDataReader.GetSchemaTable返回所执行查询的列元数据。我想知道是否有类似的方法可以为给定的查询提供表元数据?我的意思是涉及哪些表以及它有哪些别名。

在我的应用程序中,我收到查询,并且需要附加where以编程方式子句。使用GetSchemaTable(),我可以获得列元数据及其所属的表。但即使表有别名,它仍然返回真实的表名。有没有办法获取该表的别名?

以下代码显示获取列元数据。

const string connectionString = "your_connection_string";
string sql = "select c.id as s,c.firstname from contact as c";

using(SqlConnection connection = new SqlConnection(connectionString))
using(SqlCommand command = new SqlCommand(sql, connection))
{
    connection.Open();
    SqlDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo);
    DataTable schema = reader.GetSchemaTable();
    foreach (DataRow row in schema.Rows)
    {
        foreach (DataColumn column in schema.Columns)
        {
            Console.WriteLine(column.ColumnName + " = " + row[column]);
        }
        Console.WriteLine("----------------------------------------");
    }
    Console.Read();
}

这将正确地为我提供列的详细信息。但当我看到BaseTableName对于列Id,它正在给予contact而不是别名c。有什么方法可以从上面这样的查询中获取表架构和别名吗?

任何帮助都会很棒!

Edit

虽然我可以使用 Rob 建议的执行计划,但我很感激任何替代的简单方法。

回答 Tomekszpakowicz 的问题

您(或您的应用程序)是来源吗 有问题的查询?在这种情况下 你应该知道别名。

我不是查询的作者。我们有一个系统,用户可以在其中输入查询。我们使用我上面解释的方法从中构建列。这些详细信息将被保留,其他用户可以使用它,例如添加新条件等。因此,我们需要根据我们拥有的信息动态构建 SQL。因此,当列有别名并且我们没有获取别名时,构造的 where 子句将无效。

Thanks


简短回答

这行不通。根据设计,您无法从结果模式中获取表别名。并且您不能依赖能够从查询执行计划中获取它们。

长答案

当您获得 SQL 查询的结果时,该查询已经被解析、验证、优化、编译成某种内部表示并执行。别名是查询“源代码”的一部分,通常会在步骤 1 和 2 附近的某个地方丢失。

执行查询后,唯一可以被视为表的东西是a)真实的物理表和b)被视为单个匿名表的返回数据。两者之间的一切都可以转变或完全优化。

如果 DBMS 需要保留别名,那么优化复杂查询实际上是不可能的。

可能的解决方案

我建议重述一个问题:

  1. 您(或您的应用程序)是相关查询的来源吗?在这种情况下,您应该知道别名。

  2. 如果您收到其他人提供的查询...那么...这取决于您为什么添加原因。

    • 在最坏的情况下,您必须自己解析查询。

    • 在最好的情况下,您可以让他们访问视图而不是真实的表,并将 where 子句放入视图中。


简单而丑陋的解决方案

如果我正确理解您的要求:

  • 用户 A 在您的程序中输入查询。

  • 用户 B 可以运行它(但不能编辑它)并看到返回的数据。 此外,她可以使用您提供的某种小部件根据返回的列添加过滤器。

  • 您不想在应用程序内部应用过滤器,而是将它们添加到查询中,以避免从数据库中获取不必要的数据。

在这种情况下:

  • 当 A 编辑查询时,尝试运行它并收集返回列的元数据。 如果ColumnNames 不是唯一的,向作者抱怨。 通过查询存储元数据。

  • 当B添加过滤器(基于查询元数据)时,存储两个列名 和条件。

  • 执行时:

    • 检查过滤器列是否仍然有效(A 可能已更改查询)。 如果没有,请删除无效过滤器和/或通知 B.

    • 执行查询,如下所示:

       select *
       from ({query entered by A}) x
       where x.Column1 op1 Value1
           and x.Column2 op2 Value2
      

如果您想优雅地处理数据库架构更改,您需要添加一些额外的检查以确保元数据与查询实际返回的内容一致。

安全说明

您的程序将把用户 A 编写的查询直接传递到数据库。 至关重要的是,您使用数据库连接来执行此操作的权限不超过 A 的数据库权限。 否则,您将要求基于 SQL 注入的漏洞利用。

推论

如果出于安全原因用户 A 无权直接访问数据库,则不能使用上述解决方案。

在这种情况下,确保其安全的唯一方法是确保您的应用程序理解 100% 的查询,这意味着在您的程序中解析查询并仅允许您认为安全的操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从查询中获取表架构 的相关文章

  • 该组件没有由 uri 标识的资源

    我想创建一个通用数据网格以在我的所有视图 用户控件上使用 这是我的结构 Class Library called Core Class called ViewBase public class ViewBase UserControl pu
  • 获取家庭成员

    假设以下家庭 其构建架构是 create table PersonConn child int parent int insert into PersonConn values 1 2 insert into PersonConn valu
  • C# Julian 日期解析器

    我在电子表格中有一个单元格 它是 Excel 中的日期对象 但当它来自 C1 的 xls 类时 它会变成双精度型 类似于 2009 年 1 月 7 日的 39820 0 我读到这是儒略日期格式 有人可以告诉我如何在 C 中将其解析回 Dat
  • java mysql 准备好的语句

    我正在尝试使用 java 向数据库中进行简单的插入 它告诉我我的 sql 语法已关闭 但是 当我复制打印出来的字符串并将其放入 phpmyadmin 中的 sql 命令中时 它会正确执行该命令 并且我似乎无法弄清楚 java 中的字符串查询
  • 如何使用 MySQL 的 LOAD DATA LOCAL INFILE 在导入 CSV 时将字符串日期更改为 MySQL 日期格式

    我正在使用 MySQL 的 LOAD DATA LOCAL INFILE SQL 语句将数据从 CSV 文件加载到现有数据库表中 下面是一个 SQL 语句示例 LOAD DATA LOCAL INFILE file csv INTO TAB
  • 如何在 C# 中以编程方式创建柔和的颜色?

    根据所需的颜色数量均匀分布地生成它们 如果指定的计数为 8 则看起来像这样 List
  • SQLite HAVING 比较错误

    我有一个测试 SQLite 表 用于存储带有值的报告数据 CREATE TABLE IF NOT EXISTS test fact daily revenue date TEXT revenue NUMERIC product TEXT I
  • EasyNetQ 模型关闭

    我使用 EasyNetQ 实现了一个简单的 RabbitMQ 客户端 连接后 我收到一条通知 队列模型关闭 这是我的代码 var bus RabbitHutch CreateBus String Format host 0 hostName
  • 找不到 Microsoft.Office.Interop Visual Studio

    我正在开发一个使用 C 发送电子邮件的应用程序 该应用程序将能够使用邮件模板等 问题是我无法找到任何 Office Interop 引用 这意味着我无法使用 Outlook 我的计算机上安装了 Office 但我也尝试从此链接安装 PIAh
  • 更改迁移中的自动​​增量值(PostgreSQL 和 SQLite3)

    我有一个托管在 Heroku 上的项目 想要更改表的自动增量起始值 我在本地使用 SQLite3 Heroku 使用 PostgreSQL 这是我在迁移中所拥有的 class CreateMytable lt ActiveRecord Mi
  • 设置 Form.KeyPreview = true 的缺点?

    我想知道 Form KeyPreview 属性实际上有什么用处 它为什么存在以及将其设置为 true 会带来什么 风险 我想它一定有some负面影响 否则它根本不应该存在 或者至少默认情况下是正确的 EDIT 我很清楚what确实如此 我问
  • 如何在 Visual Studio 中更改 Azure 数据库表的列顺序

    我整个下午都在寻找在 MS Visual Studio 2022 中重新排序 Azure 数据库表列的方法 没有运气 在其他应用程序中 可以通过拖动或剪切和粘贴轻松重新排列列 这里无能为力 此时 我什至不确定可以在 VS 中移动列 我只对
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • CompileAssemblyFromDom 抛出访问被拒绝异常

    代码 using var codeProvider new CSharpCodeProvider var compilerParameter new CompilerParameters assemblies assemblyName fa
  • SQL 删除表并重新创建并保留数据

    在我们最初的设计中 我们搞砸了表中的外键约束 现在表已充满数据 我们无法在不删除表中所有记录的情况下更改它 我能想到的唯一解决方案是创建一个备份表并将所有记录放在那里 然后删除所有记录 更改表并开始将它们添加回来 还有其他 更好 的想法吗
  • 使用 JSON 参数的 Postgres 批量 INSERT 函数

    这是一个plpgsqlpostgres 的函数9 6 它试图INSERT一行 如果插入没有失败 由于违反键约束 那么它会运行更多命令 CREATE FUNCTION foo int text text RETURNS void AS BEG
  • “你好世界!!”在 .NET 4 中生成 3500 个页面错误

    我正在运行 Windows Vista 和 Visual Studio 2010 使用 NET 4 2 GB RAM 和大约 800 MB 可用空间 我创建了一个 Windows 窗体应用程序 但没有向其中添加任何代码 只需在发布模式下编译
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • VB.NET 中的静态方法实现

    我很困惑Static在 VB NET 中的实现 在 C 中 我们可以创建静态类和静态方法来为我们的应用程序编写实用方法 现在 VB NET 让我们创建Module代替静态类 如果我们在模块中创建一个方法 默认情况下它会变成静态的 但在我的应

随机推荐

  • 将 rowversion 转换为 bigint

    在我的 C 程序中 我不想使用字节数组 因此我将 rowversion 数据类型转换为 bigint SELECT CAST version AS BIGINT FROM dbo mytable 所以我收到一个数字而不是字节数组 这种转换总
  • 在 sphinx 文档中包含独立的 HTML 页面

    对于我的项目的大部分文档 我更喜欢标准的 sphinx 布局 然而 对于登陆页面 我更喜欢使用自定义 HTML CSS JS 而不使用普通 sphinx 网站的任何布局 目录或侧边栏 有没有一种方法可以在 sphinx 生成的网站中包含原始
  • 自定义属性未在样式和主题内解析

    我有一个带有自定义主题的 Android 应用程序 该应用程序是 2 3 年前开发的 我有这个风格attr xml资源文件
  • 如何在同一端口 4200 上运行 Angular 4 应用程序和 NodeJS api 以进行生产和开发?

    我已经创建了 Angular 4 应用程序 我可以使用它来运行它ng serve open它运行在localhost 4200 我想要的是我还使用创建了 apinodejs现在在同一个角度项目中我想运行该 APIlocalhost 4200
  • 这个 128 位整数乘法在汇编 (x86-64) 中如何工作?

    我正在阅读计算机系统 程序员的视角作业是描述这个算法是如何工作的 C函数 void store prod int128 dest int64 t x int64 t y dest x int128 y 集会 movq rdx rax cqt
  • 如何写下 rspec 来测试救援块?

    我有这样的方法 def className def method name some code rescue some code and error message end end 那么 如何写下 rspec 来测试救援块 如果你想拯救 就
  • 从 WaitHandle.Wait 构造任务

    我选择返回Task
  • CodeIgniter - 如何检查每种方法使用的会话

    假设我的控制器名为Book 我有很多方法 比如get book read book remove book 如果没有用户登录 则无法使用类中的任何方法 我可以获得user id来自会话 我的问题是 检查是否存在的最佳方法是什么user id
  • 在 Scala 中,如何从可序列化的类型创建 TypeTag? [复制]

    这个问题在这里已经有答案了 在 Scala 反射中 通常可以使用 TypeCreator 从 Type 构造 TypeTag object TypeUtils import ScalaReflection universe def crea
  • Slim 3在中间件中获取当前路由

    我想在中间件类中获取当前 I 路由的名称 以前 在 Slim 2 中 您可以像这样获取当前路线 route this gt app gt router gt getCurrentRoute 但这个功能在Slim 3 0版本中已经被删除了 我
  • 如何尝试多个 SELECT 直到获得结果?

    如果我想以递减精度搜索表中的单行 例如像这样 SELECT FROM image WHERE name LIKE text AND group id 10 LIMIT 1 当这没有给我结果时 尝试这个 SELECT FROM image W
  • C++ 字符串排序像人类一样吗?

    我想按照人类对字母数字字符串进行排序的方式对其进行排序 即 A2 位于 A10 之前 a 当然位于 Z 之前 有没有什么方法可以不写迷你解析器 理想情况下 它还会将 A1B1 放在 A1B10 之前 我看到问题了 Microsoft SQL
  • 如何将一个数据帧映射到另一个数据帧(python pandas)?

    给定这两个数据帧 如何获得预期的输出数据帧 长的方法是循环遍历数据帧的行iloc然后使用map转换后的函数df2 to a dict将 x 和 y 映射到它们的分数 这看起来很乏味 并且在大型数据帧上运行需要很长时间 我希望有一个更清洁的解
  • 使用 python 验证 SSL 中的对等点

    我试图找出如何通过 python 中的服务器验证自签名证书 我在谷歌上找不到太多数据 我还想确保服务器网址 预先感谢您的任何见解 从我的第一个回复的评论中 我发现人们普遍误解了 验证证书的含义 我会尝试在这里写一个简短的解释 以消除一些幻想
  • JSON 中的根节点

    我的任务是定义两个网络应用程序之间的通信 我决定为此使用 JSON JSON 中具有根节点的情况有多常见 假设我们有一个汽车对象 这是以 Car 为根节点的 JSON Car Make Mustang YearBuilt 1999 现在假设
  • JVM 如何开始寻找类?

    我很好奇 JVM 寻找执行程序的所有位置 我更感兴趣的是了解 JVM 查找类文件的顺序和位置 例如它是否查找 java 库 扩展库 类路径等任何目录 例如调用 java 的当前目录 我对 JVM 行为更感兴趣 而不是类加载器如何加载类 我知
  • 如何缩放图片框中的某个点

    这是我的代码 我可以缩放图片框 但不能在某一点缩放 旋转鼠标滚轮时如何缩放到鼠标点 变量是 private double m dZoomscale 1 0 THIS IS THE ZOOM SCALE TO WHICH EACH OBJEC
  • SQLite 数据库文件支持的最大表数

    即使读完之后SQLite 限制我找不到最大表数一个SQLite数据库文件可以容纳 所以 我想知道是否 SQLite数据库可以容纳的最大表数有限制吗 SQLite 数据库文件中包含数千个小表是一个问题吗 SQLite 数据库文件中的许多表会影
  • 将 github 个人访问令牌与 TortoiseSVN 结合使用

    Github 下个月将关闭密码访问 因此我生成了个人访问令牌 PAT 然后 我尝试使用以下 URL 查看现有存储库的新副本 https 我 电子邮件受保护 我 myrepo git 其中 ghp blahblahblah 是我的 PAT 我
  • 从查询中获取表架构

    As per MSDN SqlDataReader GetSchemaTable返回所执行查询的列元数据 我想知道是否有类似的方法可以为给定的查询提供表元数据 我的意思是涉及哪些表以及它有哪些别名 在我的应用程序中 我收到查询 并且需要附加