Convert date from AS/400 database file - sql

I'm using MS SQL Server and am Trying to convert the date and time data into something useful for PowerBi and
can't get the time to work, Date is fine:
USE [CDCP_AEP]
GO
select *
from
(SELECT [H1PROD]
,convert(DATE,right('0'+str([H1DTTR],len([H1DTTR])),6),102) as 'AssyDate'
,[H1TMTR]
,right('000000'+str([H1TMTR],len([H1TMTR])),6) 'TempTime'
,[H1TYPE]
,[H1LOT]
,[H1SORD]
from [AEBPCSUSRF].[JHP1]
where [H1TYPE] = 'AF' and [H1LOT] <> '')a
left join
(select [P1PROD]
,[P1LOT]
from [AEBPCSUSRF].[PLA1])b
on a.[H1LOT] = b.[P1LOT]
GO
This is the result I get with the above code:
If I change the date (H1TMTR) line to
,convert(TIME,right('000000'+str([H1TMTR],len([H1TMTR])),6)) as 'AssyTime'
I get the following error:
"Msg 241, Level 16, State 1, Line 4
Conversion failed when converting date and/or time from character string."
Any tips? Thanks in advance!

You can convert by padding, substring'ing, and putting colons in between the parts like so:
DECLARE #H1TMTR VARCHAR(6)='155509'
SELECT CONVERT(TIME,
SUBSTRING(RIGHT('000000' + #H1TMTR,6),1,2) + ':'
+ SUBSTRING(RIGHT('000000' + #H1TMTR,6),3,2) + ':'
+ SUBSTRING(RIGHT('000000' + #H1TMTR,6),5,2)
) AS [Time]
Since you are doing this for PowerBI, I presume you will be doing this quite a bit. You should make a scalar function that performs this task on a column so it only needs written once.

Related

Parsing txt file with substring

I inherited a SQL code from my previous co-worker. The script was working the last time I ran it but it returns an error when I tried it today. Surprisingly the code is working on my colleague's PC. I double-check the SQL server database and we are using the same collation, Latin1_General_CS_AS. I did many tests, changing windows system locale etc however none of them work, the error is this:
Msg 207, Level 16, State 1, Line 141
Invalid column name 'Value'.
Msg 207, Level 16, State 1, Line 141
Invalid column name 'Value'.
...
However, I couldn't get it! why it is working on one system and not on another! Does anybody has any idea or alternative solution for the substring part.
DROP TABLE IF EXISTS #VievingLive0
SELECT
ProdDay, -- date
HouseId, -- ID
CAST(SUBSTRING(RowText, 2, CHARINDEX('_', RowText, 2)-2) AS INT) AS ChannelId, -- Channel ID
CASE WHEN LEN(s.Value) = 14 THEN LEFT(s.Value, 2) ELSE STUFF(LEFT(s.Value, LEN(s.Value)-12), 3, 0, '_') END AS Individs, -- list of persons
(LEN(s.Value)-12)/2 AS CntIndiv, -- number of persons watching
DATEADD(SECOND, substring(s.Value,LEN(s.Value)-11,2)*3600+substring(s.Value,LEN(s.Value)-9,2)*60+substring(s.Value,LEN(s.Value)-7,2), CAST(ProdDay AS DATETIME)) AS ViewFrom, -- time from
DATEADD(SECOND, substring(s.Value,LEN(s.Value)-5 ,2)*3600+substring(s.Value,LEN(s.Value)-3,2)*60+substring(s.Value,LEN(s.Value)-1,2)+1, CAST(ProdDay AS DATETIME)) AS ViewTo -- time to
INTO #VievingLive0
FROM #All_TX4_files
CROSS APPLY STRING_SPLIT(SUBSTRING(RowText, PATINDEX('%_[A-Za-z][A-Za-z][A-Za-z0-9]%', SUBSTRING(RowText, 2, LEN(RowText)))+2, LEN(RowText)), '_') AS s -- extracting individual vieiwng statemenets from the row
WHERE LEFT(RowText, 1) = 'V' -- LIVE viewing rows
I am trying to parse this format txt:
H98500410_0
W1941.51
Pab_2467211514110343733611_W2898.81
V100_0_2_210_ab075700080859_ab081100081259_ab081700081959_ab082800083059_ab083400083559_ab110600110959_ab111300111459_ab113500115059_ab115300120259_ab120300120359_ab120400123059_ab123100123559_ab124800125359_ab173200173259_ab191200191359_ab191600191759

Error in Openquery Stored Procedure

To keep this as simple as possible I have just copied the line of code causing an error. I'm trying to run a openquery in a stored procedure and keep getting the following error:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '*'.
I'm pretty sure it is to do with where I have quotations but I really need a second pair of eyes as I have tried all sorts of combinations:
SET #SQL_ResultID = 'SELECT * FROM OPENQUERY([23-SQL3000], ''SELECT ResultID FROM [Portfolio].[dbo].[Program] P INNER JOIN [Portfolio].[dbo].[Results] A ON P.ProgramID = A.ProgramID WHERE ProgramName = ''''' + #P + ''''' AND ResultsName = ''''' + #A + ''''''')';
Thanks in advance

Getting various errors using dynamic SQL

SET #SQLSTATEMENT = 'INSERT INTO #MAX_STORAGE
SELECT MAX(A.[ROW])
FROM
(SELECT *
FROM [DATABASE].[dbo].[Refined_Est_Probability_09_MODIFIED]
WHERE
[FIPST_ENT] = ' + #FIPST_ENT + '
AND [FIPCNTY_ENT] = ' + #FIPCNTY_ENT + '
AND [SIC_ENT] = ' + #SIC2_ENT + '
AND [FMSZ_ENT] = ' + #FMSZENT_ENT + '
AND [ESTABLISHMENTS_AVAILABLE_FMSZEST <= ' + #MAXIMUM_FMSZEST+'] > 0) A'
EXEC(#SQLSTATEMENT)
I was running the dynamic SQL query above as part of a stored procedure I had written and got the following error:
Msg 207, Level 16, State 1, Line 7
Invalid column name 'A'.
I then changed my query so that it looked like this (eliminated the alias A):
SET #SQLSTATEMENT =
'INSERT INTO #MAX_STORAGE
SELECT
MAX([ROW])
FROM
(SELECT *
FROM [DATABASE].[dbo].[Refined_Est_Probability_09_MODIFIED]
WHERE [FIPST_ENT] = ' + #FIPST_ENT + '
AND [FIPCNTY_ENT] = ' + #FIPCNTY_ENT + '
AND [SIC_ENT] = ' + #SIC2_ENT + '
AND [FMSZ_ENT] = ' + #FMSZENT_ENT + '
AND [ESTABLISHMENTS_AVAILABLE_FMSZEST <= ' + #MAXIMUM_FMSZEST + '] > 0)'
EXEC(#SQLSTATEMENT)
But I still ran into an error (this time different):
Msg 102, level 15, state 1, line 9
Incorrect syntax near ')'
I declared the following variables earlier in the procedure with their respective data types/lengths seen next to them:
#FIPST_ENT CHAR(2)
#FIPCNTY_ENT CHAR(3)
#SIC2_ENT CHAR(2)
#FMSZENT_ENT CHAR(1)
#MAXIMUM_FMSZENT CHAR(1)
#SQLSTATEMENT VARCHAR(MAX)
Before this dynamic SQL statement was reached in the stored procedure, the temporary table #MAX_STORAGE was already created and contains only one column of datatype int.
Am I missing something I'm doing wrong? Any help would be greatly appreciated.
Thanks.
At bare minimum, you need to enclose string fields in escaped-single-quotes within the Dynamic SQL. The adaptation I show below is based on this comment on the Question:
FIPST_ENT is numeric in nature (i.e. 01-50) but cast as a character. Likewise with the other FIPCNTY_ENT and SIC2_ENT. FMSZENT is cast as a character but is sometimes numeric (i.e. 1-9) and other times non-numeric (i.e. A-C).
So it seems that only FMSZENT needs the escaped-single-quotes.
Also, using a derived query requires an alias. So whatever the initial problem was, you then introduced a new parse error by removing the alias ;-).
SET #SQLSTATEMENT =
'INSERT INTO #MAX_STORAGE
SELECT MAX(tmp.[ROW]) FROM
(SELECT * FROM [DATABASE].[dbo].[Refined_Est_Probability_09_MODIFIED]
WHERE [FIPST_ENT] = '+#FIPST_ENT+'
AND [FIPCNTY_ENT] = '+#FIPCNTY_ENT+'
AND [SIC_ENT] = '+#SIC2_ENT+'
AND [FMSZ_ENT] = '''+#FMSZENT_ENT+'''
AND [ESTABLISHMENTS_AVAILABLE_FMSZEST<='+#MAXIMUM_FMSZEST+'] > 0) tmp;'
Now, when it comes to debugging Dynamic SQL, the first step should be looking at what SQL you actually constructed, as it might not be what you think it should be:
PRINT #SQLSTATEMENT;

SQL fails to convert types, but why

I am trying to filter a query the following way:
declare #CubeYear as varchar(30)
--Setting it this way so it can later be easily used in SSAS Cubes
set #CubeYear = '[Date].[Year].&[2013]'
SELECT [RankingID]
,[Year]
,[Customer]
,[Rank]
FROM [OBase].[dbo].[fact_KundeRanking]
where '[Date].[Year].&[' + Year + ']' = #CubeYear
but I keep getting the following error:
Conversion failed when converting the varchar value '[Date].[Year].&[2013]' to data type int.
Does anybody know what the solution to this might be?
Try this -
where '[Date].[Year].&[' + CAST(Year as varchar(4)) + ']' = #CubeYear

SQL Sproc Parameters: Setting Default Date value

I am trying to create a Stored Procedure that will be used for a Report and I want the 2 date parameters to have a DEFAULT value of today's date and 1 month prior.
Is the below the proper way to do this? I was reading elsewhere that I should use COALESCE...(SEE HERE)This is a touchy production system so I wanted to double check before I went forward.
CREATE PROCEDURE spCaseNoteReport
-- Add the parameters for the stored procedure here
#ContactStartDate DateTime = null,
#ContactEndDate DateTime = null
AS
IF #ContactStartDate is null
SET #ContactStartDate = dateadd(m,-1, CONVERT(date, GETDATE()))
IF #ContactEndDate is null
SET #ContactEndDate = CONVERT(date, GETDATE())
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT (id.LastName + ', ' + id.FirstName) AS 'MemberName'
,c.ContactDate
,Li.ItemDescription AS 'Location'
,c.PresentAtContact
,c.ContactDetails
,c.InsertUser
,c.TimeSpentUnits
FROM dbo.tblCaseNotes c
inner join dbo.tblIdentificationMap id
on c.PersonID = id.PersonID
left outer join dbo.tblCaseNoteContactLocation L
on c.Casenoteid = L.Casenoteid
inner join dbo.tblCaseNotesMaintItem Li
on L.ContactLocationID = Li.ItemID
WHERE c.ContactDate BETWEEN #ContactStartDate AND #ContactEndDate
ORDER BY MemberName, c.ContactDate, c.InsertUser
END
continued
So when I actually tried to run the CREATE PROCEDURE for this I get the following errors -->
Msg 243, Level 16, State 1, Procedure spCaseNoteReport, Line 12
Type date is not a defined system type.
Msg 243, Level 16, State 1, Procedure spCaseNoteReport, Line 14
Type date is not a defined system type.
Nothing wrong with this approach. I use it myself.
Parameter defaults can only be constants or udfs so the alternative is to use udfs which honestly doesn't really help.
Edit: best way to remove a time component from datetime
DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
See this excellent SO Q+A "Most efficient way in SQL Server to get date from date+time?" (not mine!)