在结果中强制 TableName.ColumnName
Force TableName.ColumnName in Results
我怀疑纯粹 SQL 我想要完成的事情是否可行,但我想确保我没有遗漏任何东西。
我想强制完整的 table 名称成为结果集中列名称的一部分,而不必分别为每一列添加别名。即:
SELECT Table1.* FROM Table1;
这应该输出如下内容:
Table1.ID
Table1.Col1
Table1.Col2
1
Value1
Value2
这主要用于动态 LEFT JOINS 的查询中,第二个 table 在某些列名中有重叠。意思是,根据用例,它可能只查询第一个 table(无连接)或两者。
结果集的解析器也知道它是否需要只关注第一个 table 或两个 table。这样做会很好:
table1Object.ID = reader["Table1.ID"];
table2Object.ID = reader["Table2.ID"];
我可以硬编码每个列名和别名。 IE,类似于:
SELECT Table1.ID As Tab1ID, ...other columns... FROM Table1
当然,如果我以后添加任何新字段,我必须更改该查询。
我还可以从数据库中查询 table 模式并在 C# 中动态构建查询并为所有内容提供别名,但我也希望避免这种情况。
它可能是 MySql,但几年前我依稀记得得到结果集,如果有一个连接并且每个 table 中的列有冲突,它会 return 列名称为 'TableName.ColumnName'。当然,这并没有真正解决我提到的问题,因为它只针对冲突而不是每一列都这样做(如果你没有加入,你就没有冲突)。
给出的表格和示例数据如下:
CREATE TABLE dbo.Parent(ID int, ShipDate date, floob int);
CREATE TABLE dbo.Child (ID int, ParentID int, splunge int);
INSERT dbo.Parent(ID, ShipDate, floob) SELECT 1, GETDATE(), 5;
INSERT dbo.Child(ID, ParentID, splunge) SELECT 1, 1, 12;
您可以像这样创建一个过程:
CREATE PROCEDURE dbo.BuildSomeSQL
@parentTable nvarchar(256),
@parentColumn nvarchar(128),
@childTable nvarchar(256),
@childColumn nvarchar(128)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql nvarchar(max) = N'SELECT ' + char(13) + char(10) + ' ';
SELECT @sql += STRING_AGG(CONCAT(N'[',
PARSENAME(@parentTable,1), N'.', name, N'] = p.', name),
N',' + char(13) + char(10) + ' ')
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@parentTable);
SELECT @sql += N',' + char(13) + char(10) + ' '
+ STRING_AGG(CONCAT(N'[',
PARSENAME(@childTable,1), N'.', name, N'] = c.', name),
N',' + char(13) + char(10) + ' ')
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@childTable);
SET @sql += char(13) + char(10) + N'FROM ' + @parentTable + N' AS p
INNER JOIN ' + @childTable + N' AS c
ON p.' + @parentColumn + N' = c.' + @childColumn + N';';
PRINT @sql;
EXEC sys.sp_executesql @sql;
END
GO
然后你这样称呼它:
EXEC dbo.BuildSomeSQL
@parentTable = N'dbo.Parent',
@parentColumn = N'ID',
@childTable = N'dbo.Child',
@childColumn = N'ParentID';
打印输出:
SELECT
[Parent.ID] = p.ID,
[Parent.ShipDate] = p.ShipDate,
[Parent.floob] = p.floob,
[Child.ID] = c.ID,
[Child.ParentID] = c.ParentID,
[Child.splunge] = c.splunge
FROM dbo.Parent AS p
INNER JOIN dbo.Child AS c
ON p.ID = c.ParentID;
执行输出:
Parent.ID
Parent.ShipDate
Parent.floob
Child.ID
Child.ParentID
Child.splunge
1
2022-01-26
5
1
1
12
我怀疑纯粹 SQL 我想要完成的事情是否可行,但我想确保我没有遗漏任何东西。
我想强制完整的 table 名称成为结果集中列名称的一部分,而不必分别为每一列添加别名。即:
SELECT Table1.* FROM Table1;
这应该输出如下内容:
Table1.ID | Table1.Col1 | Table1.Col2 |
---|---|---|
1 | Value1 | Value2 |
这主要用于动态 LEFT JOINS 的查询中,第二个 table 在某些列名中有重叠。意思是,根据用例,它可能只查询第一个 table(无连接)或两者。
结果集的解析器也知道它是否需要只关注第一个 table 或两个 table。这样做会很好:
table1Object.ID = reader["Table1.ID"];
table2Object.ID = reader["Table2.ID"];
我可以硬编码每个列名和别名。 IE,类似于:
SELECT Table1.ID As Tab1ID, ...other columns... FROM Table1
当然,如果我以后添加任何新字段,我必须更改该查询。
我还可以从数据库中查询 table 模式并在 C# 中动态构建查询并为所有内容提供别名,但我也希望避免这种情况。
它可能是 MySql,但几年前我依稀记得得到结果集,如果有一个连接并且每个 table 中的列有冲突,它会 return 列名称为 'TableName.ColumnName'。当然,这并没有真正解决我提到的问题,因为它只针对冲突而不是每一列都这样做(如果你没有加入,你就没有冲突)。
给出的表格和示例数据如下:
CREATE TABLE dbo.Parent(ID int, ShipDate date, floob int);
CREATE TABLE dbo.Child (ID int, ParentID int, splunge int);
INSERT dbo.Parent(ID, ShipDate, floob) SELECT 1, GETDATE(), 5;
INSERT dbo.Child(ID, ParentID, splunge) SELECT 1, 1, 12;
您可以像这样创建一个过程:
CREATE PROCEDURE dbo.BuildSomeSQL
@parentTable nvarchar(256),
@parentColumn nvarchar(128),
@childTable nvarchar(256),
@childColumn nvarchar(128)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql nvarchar(max) = N'SELECT ' + char(13) + char(10) + ' ';
SELECT @sql += STRING_AGG(CONCAT(N'[',
PARSENAME(@parentTable,1), N'.', name, N'] = p.', name),
N',' + char(13) + char(10) + ' ')
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@parentTable);
SELECT @sql += N',' + char(13) + char(10) + ' '
+ STRING_AGG(CONCAT(N'[',
PARSENAME(@childTable,1), N'.', name, N'] = c.', name),
N',' + char(13) + char(10) + ' ')
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@childTable);
SET @sql += char(13) + char(10) + N'FROM ' + @parentTable + N' AS p
INNER JOIN ' + @childTable + N' AS c
ON p.' + @parentColumn + N' = c.' + @childColumn + N';';
PRINT @sql;
EXEC sys.sp_executesql @sql;
END
GO
然后你这样称呼它:
EXEC dbo.BuildSomeSQL
@parentTable = N'dbo.Parent',
@parentColumn = N'ID',
@childTable = N'dbo.Child',
@childColumn = N'ParentID';
打印输出:
SELECT
[Parent.ID] = p.ID,
[Parent.ShipDate] = p.ShipDate,
[Parent.floob] = p.floob,
[Child.ID] = c.ID,
[Child.ParentID] = c.ParentID,
[Child.splunge] = c.splunge
FROM dbo.Parent AS p
INNER JOIN dbo.Child AS c
ON p.ID = c.ParentID;
执行输出:
Parent.ID | Parent.ShipDate | Parent.floob | Child.ID | Child.ParentID | Child.splunge |
---|---|---|---|---|---|
1 | 2022-01-26 | 5 | 1 | 1 | 12 |