CREATE TABLE t1 (
id int,
name varchar(50),
PRIMARY KEY (id)
);
insert into t1 (id,name) values(1,'t1.1')
insert into t1 (id,name) values(2,'t1.2')
insert into t1 (id,name) values(3,'t1.3')
CREATE TABLE t2 (
id int,
name varchar(50),
PRIMARY KEY (id),
CONSTRAINT fk_t1_t2 FOREIGN KEY (Id) REFERENCES t1(Id)
);
insert into t2 (id,name) values(1,'t2.1')
insert into t2 (id,name) values(2,'t2.2')
insert into t2 (id,name) values(3,'t2.3')
-- SQL created manualy:
select * from t1
join t2 on t2.id = t1.id
drop table t2
drop table t1
这是一个非常简单的例子。想想一个包含大量外键引用的巨型数据库结构!
手动定义所有连接条件是一项艰巨的任务!
我想动态创建这个SQL语句!
外部引用已在数据库中定义,但在哪里?
脚本应该这样做:
select
t1.id,
t1.name,
t2.id,
it2.name
from t1
join t2 on t2.id = t1.id
有人已经解决了这个问题吗?
附录:脚本的参数是第一个Tablename和最后一个Tablename。这两个表应与所有相关的表间或参考表连接在一起。
答案 0 :(得分:3)
这样可以解决问题,但我不建议这样做。
问题:更频繁地引用同一个表(别名),加入类型(内部,左侧,......),所选列列表......
DECLARE @table AS VARCHAR(100)='YouTableName';
WITH AllColumns AS
(
SELECT pObj.name AS ParentTable
,pCol.COLUMN_NAME AS ParentColumn
,fkObj.name AS ReferecedTable
,fkCol.COLUMN_NAME AS ReferencedColumn
FROM sys.foreign_key_columns AS fkc
INNER JOIN sys.objects AS pObj ON pObj.object_id=fkc.parent_object_id
INNER JOIN INFORMATION_SCHEMA.COLUMNS AS pCol ON pCol.TABLE_NAME=pObj.name AND pCol.ORDINAL_POSITION=fkc.parent_column_id
INNER JOIN sys.objects AS fkObj ON fkObj.object_id=fkc.referenced_object_id
INNER JOIN INFORMATION_SCHEMA.COLUMNS AS fkCol ON fkCol.TABLE_NAME=fkObj.name AND fkCol.ORDINAL_POSITION=fkc.referenced_column_id
WHERE fkc.constraint_object_id IN
(
SELECT object_id FROM sys.objects AS o
WHERE o.name IN
(
SELECT tc.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc
WHERE tc.CONSTRAINT_TYPE='FOREIGN KEY'
AND tc.TABLE_NAME=@table
)
)
)
SELECT 'SELECT *
FROM ' + @table +
(
SELECT ' INNER JOIN ' + ac.ReferecedTable + ' ON ' + ac.ParentTable + '.' + ac.ParentColumn + '=' + ac.ReferecedTable + '.' + ac.ReferencedColumn + CHAR(10)
FROM AllColumns AS ac
FOR XML PATH('')
)
答案 1 :(得分:0)
Shnugo中的精彩脚本。但这有一些缺点:
dbo
模式PRINT
带有 nice 格式设置选项的语句我改进了此脚本来解决此问题:
/*
<documentation>
<summary>Create JOIN query between multiple tables dynamically.</summary>
<returns>SELECT statement from input table with INNER JOINS for all tables having foreign consttraints with input table.</returns>
<issues>Does not properly generate alias for case with multiply foreign keys for one table</issues>
<author>Konstantin Taranov</author>
<created>2019-04-22</created>
<modified>2019-04-23 by Konstantin Taranov</modified>
<version>1.1</version>
<sourceLink>https://github.com/ktaranov/sqlserver-kit/blob/master/Scripts/Create_JOIN_Query_Between_Multiple_Tables_Dynamically.sql</sourceLink>
</documentation>
*/
DECLARE @schemaName AS sysname = N'dbo';
DECLARE @tableName AS sysname = N'TableName';
DECLARE @tableFullName AS nvarchar(256) = QUOTENAME(@schemaName) + N'.' + QUOTENAME(@tableName)
DECLARE @crlf AS varchar(10) = CHAR(10);
DECLARE @tsql AS nvarchar(max);
IF LEFT(@tableName, 1) = N'[' OR LEFT(@schemaName, 1) = N'['
THROW 50001, 'Please do not use quotes in Table or Schema names! In the script it is alredy done with QUOTENAME function.', 1;
IF OBJECT_ID(@tableFullName) IS NULL
THROW 50002, 'Table is not exist in database. Please check @schemaName and @tableName variables.', 1;
WITH AllColumns
AS (SELECT
pObj.name AS ParentTable
,pCol.COLUMN_NAME AS ParentColumn
,SCHEMA_NAME(fkObj.schema_id) AS ReferecedTableSchema
,fkObj.name AS ReferecedTable
,fkCol.COLUMN_NAME AS ReferencedColumn
FROM sys.foreign_key_columns AS fkc
INNER JOIN sys.objects AS pObj ON pObj.object_id = fkc.parent_object_id
INNER JOIN INFORMATION_SCHEMA.COLUMNS AS pCol ON pCol.TABLE_NAME = pObj.name
AND pCol.ORDINAL_POSITION = fkc.parent_column_id
INNER JOIN sys.objects AS fkObj ON fkObj.object_id = fkc.referenced_object_id
INNER JOIN INFORMATION_SCHEMA.COLUMNS AS fkCol ON fkCol.TABLE_NAME = fkObj.name
AND fkCol.ORDINAL_POSITION = fkc.referenced_column_id
WHERE fkc.constraint_object_id IN
(
SELECT
object_id
FROM sys.objects AS o
WHERE o.name IN
(
SELECT
tc.CONSTRAINT_NAME AS CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc
WHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND tc.TABLE_NAME = @tableName
AND tc.TABLE_SCHEMA = @schemaName
)
))
SELECT
@tsql =
N'SELECT TOP(100) ' + QUOTENAME(@tableName) + N'.*' + @crlf +
N'FROM ' + @tableFullName +
ISNULL(
(
SELECT
@crlf + N'INNER JOIN ' + QUOTENAME(ac.ReferecedTableSchema) + N'.' + QUOTENAME(ac.ReferecedTable) + N' ON' + @crlf +
N' ' + QUOTENAME(ac.ParentTable) + N'.' + QUOTENAME(ac.ParentColumn) + ' = ' +
QUOTENAME(ac.ReferecedTable) + '.' + QUOTENAME(ac.ReferencedColumn)
FROM AllColumns AS ac FOR
XML PATH('')
), N'') + N';';
IF @tsql IS NULL
PRINT('@tsql is NULL - something went wrong!');
ELSE
PRINT(@tsql);