如何从SQL语句中获取列和表
本文关键字:获取 语句 SQL | 更新日期: 2023-09-27 17:50:59
我需要获得查询中使用的列和表,但我没有找到一种优雅的方法来实现它。我已经搜索过了,但找不到对我有用的信息。查询的格式为
select TABLE1.Id, TABLE2.Name, TABLE3.Observations, TABLE3.Adress, --and more 70 fields
from TABLE1, TABLE2, TABLE3, TABLE4
有什么好的方法可以同时完成这两项任务吗?
您的问题是SqlCommand.Parameters
是一系列SqlParameter
对象,将在查询中替换为实际值。即它们是输入参数。它们用于SqlCommand
用SQL Safe和Compatible表示所包含的参数。例如,对于您的查询,像下面这样的内容就足够了:
SqlCommand sql = new SqlCommand("SELECT TABLE1.Id, TABLE2.Name, TABLE3.Observations, TABLE3.Address FROM TABLE1, TABLE2, TABLE3, TABLE4 WHERE TABLE2.Name = @Name")
sql.Parameters.Add(new SqlParameter("@Name", SqlDbType.NVarChar, 32));
sql.Parameters["@Name"] = "Your Name";
SQL驱动程序然后将查询中的@Name
替换为'Your Name'
的SQL Safe表示。
要做你想做的,你需要解析实际的字符串,并把它分解成标记或语句。对于某些语句,这是一个复杂的过程。
根据您的需求(为了支持语法),您可以很容易地通过提取SELECT
和FROM
之间的所有内容来分解语句,在本例中,用逗号分隔字符串,然后用句点进一步分隔以获得表名和字段名。
一些示例代码应该做你想做的(目前尚未测试):
// sql.CommandText can be replaced with the raw SQL Query String
string query = sql.CommandText;
string removeSelect = query.Substring(7); // Remove the SELECT and space
string removeAfterFrom = removeSelect.Substring(0, removeSelect.IndexOf(" FROM ")); // Remove the FROM
string[] columns = removeAfterFrom.Split(','); // Get each Column
List<string> tables = new List<string>();
for (int i = 0; i < columns.Length; i++)
{
string[] columnName = columns[i].Split('.');
if (columnName.Length > 1)
if (!tables.Contains(columnName[0]))
tables.Add(columnName[0].Trim());
}
还有一点需要注意,这段代码可以很容易地修改为从FROM
子句中提取表名。
SELECT
语句,则此方法将适用于所有变体,除了那些使用通配符(*
)列名的变体,或者那些使用TOP (n)
的变体。如果必须支持TOP (n)
查询,则应该添加适当的筛选器。它还将只返回包含在列名子句中的表名。(即需要完全限定的名称:SELECT TABLE1.Name FROM TABLE1
而不是SELECT Name FROM TABLE1
。
如果您希望获得查询中指定的所有表(无论是否从中选择了任何列),您可以使用以下命令。
// sql.CommandText can be replaced with the raw SQL Query String
string query = sql.CommandText;
string removeSelect = query.Substring(7); // Remove the SELECT and space
string[] splitOnFrom = removeSelect.Split(new string[] { " FROM " }, StringSplitOptions.RemoveEmptyEntries);
string[] columns = splitOnFrom[0].Split(','); // Get each Column
string[] tables = splitOnFrom[1].Split(','); // Get each Table
columns
数组包含所有全限定列名,tables
数组包含所有全限定表名。
FROM
术语(单词)是区分大小写的。即From
, from
不能工作。如果您希望使用第一种方法并使from
不区分大小写,则可以使用以下方法:
string removeAfterFrom = removeSelect.Substring(0, removeSelect.IndexOf(" FROM ", StringComparison.CurrentCultureIgnoreCase));
对于第二个,您需要对它进行更多的修改,但这并不太难。
据我所知,没有任何内置的东西具有这个功能。(不过我敢肯定,谷歌一下就能证明我错了。)
我现在能想到的方法有很多
第一个是实际执行有问题的SQL语句(可能将其包装在begin tran
/rollback tran
中),然后从SqlDataReader
中提取列名。
第二种方法是手工生成一个基本的解析器。这可能非常简单,特别是如果您只需要支持select a.b, c, d.e from ...
语法。