我正在尝试使用以下查询做两件事:
编辑查询以获取仅在'd|'
和')()'
之间的所有日期。例如,在clndr_data中,(0||3(d|41429)()) (0||4(d|41464)( (0||0(s|09:00|f|15:00)())))
仅返回41429
。下面的查询返回'|d'
之后的所有日期。
将输出存储为View(Proj_ID,Clndr_ID,日期)
DECLARE @project_name varchar(50) = 'NA63-TEN-20-05-12-01'
DECLARE @project_id int = (SELECT [proj_id] FROM [PMDB].[dbo]. [PROJECT] WHERE [proj_short_name] = @project_name)
DECLARE @calendar int = (SELECT [clndr_id] FROM [PMDB].[dbo].[PROJECT] WHERE [proj_short_name] = @project_name)
DECLARE @clndr_id int
DECLARE @walker int = 0
DECLARE @holder varchar(MAX)
DECLARE @date date
DECLARE @temp_tb table([id] int , [value] varchar(50))
SET @holder = (SELECT [clndr_data] FROM [PMDB].[dbo].[CALENDAR] WHERE [clndr_id] = @calendar )
SET @clndr_id = (SELECT [clndr_id] FROM [PMDB].[dbo].[CALENDAR] WHERE [clndr_id] = @calendar)
WHILE CHARINDEX('d|', @holder) > 0
BEGIN
SET @walker = CHARINDEX('d|', @holder) + 2
SET @date = DATEADD(D, CAST((SELECT SUBSTRING(@holder, @walker, 5)) AS int) - 2, '01/01/1900')
INSERT INTO @temp_tb VALUES (@clndr_id, @date)
SET @holder = SUBSTRING(@holder, @walker + 5, LEN(@holder))
END
SELECT * FROM @temp_tb
答案 0 :(得分:1)
我加入了您的PROJECT
和CALENDAR
表。然后将参数设置为proj_id
和clndr_id
的相应值,以便在INSERT
之前进行准备,因为date_value
列的值需要首先在{{1}内部处理}。
已连接到问题:SQL While Loop exists
DECLARE @project_name varchar(50) = 'NA63-TEN-20-05-12-01' DECLARE @project_id int DECLARE @clndr_id int DECLARE @walker int = 0 DECLARE @holder varchar(MAX) DECLARE @date date DECLARE @data varchar(MAX) DECLARE @temp_tb table([proj_id] int, [clndr_id] int , [date_value] date) SELECT @project_id = [p].[proj_id] ,@clndr_id = [p].[clndr_id] ,@holder = [c].[clndr_data] FROM [PMDB].[dbo].[PROJECT] AS [p] INNER JOIN [PMDB].[dbo].[CALENDAR] AS [c] ON [p].[clndr_id] = [c].[clndr_id] WHERE [p].[proj_short_name] = @project_name WHILE @walker <> LEN(@holder) + 1 BEGIN IF SUBSTRING(@holder, @walker, 2) = 'd|' BEGIN SET @data = SUBSTRING(@holder, @walker, 10) IF SUBSTRING(@data, LEN(@data) - 2, 3) = ')()' BEGIN SET @date = DATEADD(D, CAST(SUBSTRING(@data, 3, 5) AS int) -2, '01/01/1900') INSERT INTO @return_tb VALUES (@project_id, @clndr_id, @date) END END SET @walker = @walker + 1 END SELECT * FROM @temp_tb
如果要将其另存为WHILE
,请首先将上面的代码创建为view
。
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: -- Create date: -- Description: -- ============================================= CREATE FUNCTION GetProjectDates ( @project_name varchar(50) ) RETURNS @return_tb TABLE([proj_id] int, [clndr_id] int , [date_value] date) AS BEGIN -- Add the SELECT statement with parameter references here DECLARE @project_id int DECLARE @clndr_id int DECLARE @walker int = 0 DECLARE @holder varchar(MAX) DECLARE @date date DECLARE @data varchar(MAX) SELECT @project_id = [p].[proj_id] ,@clndr_id = [p].[clndr_id] ,@holder = [c].[clndr_data] FROM [PMDB].[dbo].[PROJECT] AS [p] INNER JOIN [PMDB].[dbo].[CALENDAR] AS [c] ON [p].[clndr_id] = [c].[clndr_id] WHERE [p].[proj_short_name] = @project_name WHILE @walker <> LEN(@holder) + 1 BEGIN IF SUBSTRING(@holder, @walker, 2) = 'd|' BEGIN SET @data = SUBSTRING(@holder, @walker, 10) IF SUBSTRING(@data, LEN(@data) - 2, 3) = ')()' BEGIN SET @date = DATEADD(D, CAST(SUBSTRING(@data, 3, 5) AS int) -2, '01/01/1900') INSERT INTO @return_tb VALUES (@project_id, @clndr_id, @date) END END SET @walker = @walker + 1 END RETURN END GO
然后将以下代码另存为视图:
SELECT * FROM [GetProjectDates]('NA63-TEN-20-05-12-01')
答案 1 :(得分:0)
我不确定,但可能会在下面的查询中为您提供帮助。正如我所假设的那样,日期值仅是5位数字。
create table #yourtable (
cola varchar(1000)
)
;
insert into #yourtable
values ('(0||3(d|41429)())')
insert into #yourtable
values ('(0||4(d|41464)( (0||0(s|09:00|f|15:00)())))')
select SUBSTRING(cola,9,5)
from #yourtable
where PATINDEX('%[0-9][0-9][0-9][0-9][0-9])()%', cola )>0