如何在SQL Server中将一个列值拆分为两个单独的列?

时间:2016-10-22 15:58:07

标签: sql-server-2008 tsql

Select physical_name 
From Sys.database_files

如何将输出文件路径分成两部分?

例如:

Select physical_name 
From Sys.database_files

生成此输出:

C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\master.mdf
C:\Program Files\MSSQL\DATA\muser.mdf

我想改为:

Col1                                                                   col2
----------------------------------------------------------------------------------
C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA   master.mdf
C:\Program Files\MSSQL\DATA                                            muser.mdf

3 个答案:

答案 0 :(得分:0)

您需要的是从tsql中的路径中提取文件名的功能。这不存在,但是有一个“反向技巧”来获得lastindexof,它将找到与SUBSTRING函数相关的最后一个反斜杠。这已经有了解决方案:https://stackoverflow.com/a/19505918/1132334以及更多:Is there a LastIndexOf in SQL Server?

答案 1 :(得分:0)

我个人不会使用上面链接中引用的标量函数,因为标量函数会减慢速度。内联表值函数(itvf)是要走的路。在这种情况下应该没什么关系,因为你可能不会处理很多行,但是,对于标量UDF的高性能替代方案,请查看本文:http://www.sqlservercentral.com/articles/T-SQL/91724/

对于sys.database_files,您可以这样做:

WITH prep AS
(
  SELECT physical_name, li = LEN(physical_name)-CHARINDEX('\',REVERSE(physical_name))
  FROM sys.database_files
)
SELECT fpath = SUBSTRING(physical_name,1,li), fname = SUBSTRING(physical_name,li+2,8000)
FROM prep;

对于这类事情,这是标量udfs的可重用替代方法:

-- A high-performing, re-usable itvf to split a string on the last delimiter.
CREATE FUNCTION dbo.itvf_getfilename (@fullname varchar(255), @delimiter char(1))
RETURNS TABLE AS RETURN
SELECT fpath = SUBSTRING(@fullname,1,li),
       fname = SUBSTRING(@fullname,li+2,8000)
FROM (VALUES (LEN(@fullname) - CHARINDEX('\',REVERSE(@fullname)))) prep(li);

这是一个用法示例:

DECLARE @fullname varchar(255) = 'C:\Program Files\Microsoft SQL Server\MSSQL12.SQLSERVER2014X64\MSSQL\DATA AjbTest.mdf';
SELECT fpath, fname FROM dbo.itvf_getfilename (@fullname,'\');

......而且,对着桌子:

SELECT fpath, fname
FROM sys.database_files dbf
CROSS APPLY dbo.itvf_getfilename(dbf.physical_name,'\');

答案 2 :(得分:0)

尝试以下代码

Select physical_name AS [FullPath] ,
LEFT(physical_name,LEN(physical_name) - charindex('\',reverse(physical_name),1) + 1) [Directory],
REVERSE(LEFT(REVERSE(physical_name),CHARINDEX('\', REVERSE(physical_name), 1) - 1)) [Filename]
From Sys.database_files