如何使用 SQL Server 连接选择中的所有列

Posted

技术标签:

【中文标题】如何使用 SQL Server 连接选择中的所有列【英文标题】:How to concatenate all columns in a select with SQL Server 【发布时间】:2012-12-07 10:33:48 【问题描述】:

我需要我的选择有这样的模式:

 SELECT '<text> ' + tbl.* + ' </text>' FROM table tbl;

理想的解决方案是将所有列用逗号分隔,以便获得该输出:

表 1 的两列 SQL 结果:

'<text>col1, col2</text>'

表 2 三列的 SQL 结果:

'<text>col1, col2, col3</text>' 

我尝试像这样使用CONCAT(...) 函数:

SELECT CONCAT('<text>', tbl.*, '</text>')
FROM table2 tbl

但我知道它不是那么简单,因为列数可变。

有什么简单的方法可以解决这个问题吗?

我使用的是 SQL Server 2008 R2。

【问题讨论】:

CONCAT 是 SQL Server 2012 中的新功能 是的,后来我看到了,因为错误首先集中在星号上(*)我认为该功能不可用。 【参考方案1】:

给定表名的任意数量的列; 如果您需要用&lt;text&gt; 包裹的列名

DECLARE @s VARCHAR(500)

SELECT @s =  ISNULL(@s+', ','') + c.name   
FROM  sys.all_columns c join sys.tables  t 
            ON  c.object_id = t.object_id
WHERE t.name = 'YourTableName'

SELECT '<text>' + @s + '</text>'

SQL Fiddle 此处为示例

-- RESULTS 
<text>col1, col2, col3,...</text>

如果您需要选择查询结果集包装&lt;text&gt; then;

SELECT @S =  ISNULL( @S+ ')' +'+'',''+ ','') + 'convert(varchar(50), ' + c.name    FROM 
       sys.all_columns c join sys.tables  t 
       ON  c.object_id = t.object_id
WHERE t.name = 'YourTableName'


EXEC( 'SELECT ''<text>''+' + @s + ')+' + '''</text>'' FROM YourTableName')

SQL Fiddle 此处为示例

--RESULTS
<text>c1r1,c2r1,c3r1,...</text>
<text>c1r2,c2r2,c3r2,...</text>
<text>c1r3,c2r3,c3r3,...</text>

【讨论】:

不幸的是,它不适用于 jTDS 驱动程序(我使用 talend DI)。但我已经对元数据表(sysobject、syscolumns 和 systypes)进行了一些查询。无论如何,您的解决方案向我展示了要遵循的方式。【参考方案2】:

SQL Fiddle

MS SQL Server 2008 架构设置

create table YourTable
(
  ID int identity primary key,
  Name varchar(50),
)

insert into YourTable values
('Name 1'),
('Name 2'),
('Name 3'),
('Name 4'),
('Name 5')

查询 1

select (
       select (
              select ', '+T2.N.value('./text()[1]',  'varchar(max)')
              from (
                   select T.*
                   for xml path(''), type
                   ) as T1(N)
                cross apply T1.N.nodes('/*') as T2(N)
              for xml path(''), type
              ).value('substring(./text()[1], 3)',  'varchar(max)')
       for xml path('text'), type
       )
from YourTable as T

Results

|               COLUMN_0 |
--------------------------
| <text>1, Name 1</text> |
| <text>2, Name 2</text> |
| <text>3, Name 3</text> |
| <text>4, Name 4</text> |
| <text>5, Name 5</text> |

【讨论】:

【参考方案3】:

我尝试了一种更通用的方法

Create Procedure P_GetConcatColumns(@tablename varchar(200),@Seperator Varchar(20),@StartTag Varchar(20),@EndTag Varchar(20),@WhereString Varchar(400),@OrderString Varchar(400)) as


DECLARE @TmpTableName VARCHAR(100),
        @Columns NVARCHAR(4000),
        @SQL NVARCHAR(MAX),
        @GENNAME VARCHAR(100)

Select  @GENNAME='##'+Replace(Cast(NewID() as Varchar(40)),'-','')

IF OBJECT_ID('tempdb.dbo.' + @GENNAME) IS NOT NULL
BEGIN
    EXEC('DROP TABLE ' +@GENNAME);
END




Select @SQL='SELECT TOP 1 * INTO '+@GENNAME+' FROM ' + @tablename
Exec (@SQL)



SET @TmpTableName = 'tempdb.dbo.' + @GENNAME
SELECT @Columns = 
    STUFF(
    (
    SELECT '+' + @Seperator + '+CAST(Coalesce(' + c.name + ','''') AS VARCHAR(MAX))' + CHAR(13)
    FROM tempdb.sys.columns c
    WHERE c.[object_id] = object_Id(@TmpTableName)
    FOR XML PATH(''),TYPE
    ).value('.','VARCHAR(MAX)')
    ,1,len(@Seperator)+2,'')

--SET @SQL = N'SELECT ' +''''+ @StartTag +''''+'+'+ @Columns +''''+'+'+ @EndTag + ''' FROM ' + @tablename 
SET @SQL = N'SELECT ''' +@StartTag+ '''+'+ @Columns +'+'''+ @EndTag + ''' FROM ' + @tablename 
+' '+Coalesce(@WhereString,'')
+' '+Coalesce(@OrderString,'')
Print @SQL
EXEC sp_executeSQL @SQL


--ExampleCall P_GetConcatColumns 'Arten',''',''','<test>','</test>','where id>1','Order by ID desc'

【讨论】:

【参考方案4】:

试试下面的代码:

SELECT Stuff(
(SELECT N', ' + COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME = 'YourTableName' FOR XML PATH(''),TYPE)
.value('text( [1]','nvarchar(max)'),1,2,N'')

【讨论】:

这似乎适用于 mysql 而不是 SQL-Server。但它也可能有用。【参考方案5】:

IBMDB2:使用所需的分隔符创建文件,例如delimiter='#|#' belowStep1:- 运行以下查询,您会在 query_to_execute 列中获得 SQL 语句:

select table_name, 'select '||listagg(column_name, '||''#|#''||')||' from '||trim(table_schema)||'.'||(table_name) as query_to_execute
      from qsys2.SYSCOLUMNS                                  
     where table_name in ('YOURTABLE1', 'YOURTABLE2')                             
       and table_schema = 'YOURSCHEMA'                         
     group by table_schema, table_name

Step2:- 运行上面形成的查询以获取 SQL 中的分隔文件。

Step3a(如果从原生 iSeries 运行 SQL):将结果移动到平面文件,并将平面文件导入/FTP_get 到其他平台。

Step3b(如果使用 Windows 中的查询工具运行 SQL):将结果导出到您选择的 file_name.xxx。

这样我们就可以创建一个 CSV 或一个带有我们选择的分隔符的分隔文件。

/尼拉吉库马尔

【讨论】:

嗨尼拉杰。该问题要求 SQL Server 中的答案,而不是 IBMDB2。

以上是关于如何使用 SQL Server 连接选择中的所有列的主要内容,如果未能解决你的问题,请参考以下文章

如何跟踪SQL SERVER 正在执行的语句

如何列出 SQL Server 中的所有连接?

如何使用 sql server 连接或配置 elasticsearch

如何将两个表与 SQL Server 中第二个表中引用同一列的两列连接起来

SQL Server:选择 4 个非空列并将它们连接起来

如何在 SQL Server 中连接字符串,并按不同的列排序/排序?