Run SSIS Package skipping Invalid dates - sql-server

I've a DWH Table which has Date Value stored as int.Now I wanna get all records for a day which are active on a day with conditions as start_date<=#date and End_Date>#DATE
for almost close to 2 years.
I've used a for loop and 3 variables where in hardcoded FROM_DATE and TO_DATE as 20130101 and 20150107 and the 3 variable VAR_DATE initially set TO_DATE and decreasing by 1 until it reaches FROM_DATE.
But after reaching 20150101...It's starting to insert values for 20150100,20150099 and so on..
Is there a way where in I can check to see if the VAR_DATE column being used is actually a valid date(by convert and comparing on the go) or any possible way of using a result set..
Thanks,
Vijay

Use a script to convert the integer into a string. Then parse it into a date object like so:
DateTime parsedDate;
bool parseResult = DateTime.TryParseExact(dateValue, "yyyyMMdd", null, DateTimeStyles.None, out parsedDate)
Then parseResult will be true if it's a valid date.

Related

Conversion failed when converting date and/or time from character string during update only

I have been searching for a resolution for a long time now and just can't seem to formulate a query that brings back the resolution so as a last resort I have posted here.
I have a SQL server table with a varchar column that has the date and time stored in this format
"1/1/2013 11:38:31 PM Some other text"
I needed this date and time portion of this data to be stored in another column in datetime datatype. So I created a new column called DateTimeLog of type datetime.
I then used left to chop off the extra text and convert to change the value to datetime format and got the result I would expect.
select CONVERT(DATETIME,(rtrim(left(olddate, 21)))) from mytable
results:
"2013-01-01 23:38:31.000"
So far, so good. this is what I would expect. My troubles begin when I attempt to update my new datetime column with the results of this CONVERT statement.
update mytable
SET DateTimeLog = CONVERT(DATETIME,(rtrim(left(olddate, 21)))) from mytable
I get the infamous "Conversion failed when converting date and/or time from character string" error message.
Conversion failed when converting date and/or time from character string.
I have also attempted to use cast
update mytable
SET DateTimeLog = (cast(CONVERT(DATETIME,(rtrim(left(oldtable, 21)))) as datetime)) from mytable
the error persists. As best I can tell the convert is working correctly because I can see the result set from a select, but getting that result into a new column has eluded me thus far.
thanks,
Your string isn't going to consistently be 21 characters long. Your sample data shows a single character month and a single character date. What if it's, say, 12/13/2018?
That said, you need a more robust way to isolate that timestamp. I used a PATINDEX to capture the position of the last colon in the time component, with a couple of regexes in there to account for the numbers & the AM/PM thing. Then I added 6 to it to get to the end of the string of interest.
This seems to work:
DECLARE #t TABLE (olddate VARCHAR(100));
INSERT #t
(
olddate
)
VALUES
('12/13/2018 11:38:31 PM Some other text')
,('1/1/2018 11:38:31 PM Some other text');
SELECT CAST(LEFT(olddate,PATINDEX('%:[0-9][0-9] [AP]M%', olddate)+6) AS DATETIME)
FROM #t;
Results:
+-------------------------+
| 2018-12-13 23:38:31.000 |
| 2018-01-01 23:38:31.000 |
+-------------------------+
Rextester: https://rextester.com/BBPO51381 (although the date format's a little funky on the output).

For Loop Container SSIS AssignExpression

I have table with columns Start date and end date and i need to enter
values for 2 years.I created a for loop and I am trying to load values for
every month.
For Example, My first input start Date is 10/12/2016 end date 11/11/2016. It
should be incremented with one month and inserted into table for 2 years.
For Loop Container
InitExpression: #windowStart="10/12/2016"
Evalexpression: #WindowStart<#windowMaxdate
AssignExpression: #windowStart= Dateadd("mm",1,#windowStart)
Execute sql task
SQL command:
Insert into dbo.datetemp
(WindowStart,WindowEnd ) values (?,?)
My problem is i am not getting values what i am expected and its just
returning same windowstart and windowend for every record. And loop is not coming to stop.
Guys i got the solution.
I have added a expression task inside for loop after execute sql task
#[User::WindowStart] = (DT_WSTR,24)(DT_DBTIMESTAMP) dateadd("mm",1,
(#[User::WindowStart]) )
instead adding this expression in Assign expression in for loop editor.
You are passing a string value to a #windowStart.
Create a variable #StartDate of type Datetime with the value 2016-12-10. And use the following expression:
InitExpression: #windowStart= #StartDate
Also make sure that #windowStart and #windowMaxdate are of type DateTime
Also check this similar question for more information:
How do I loop through date values stored as numbers within For Loop container?

SSRS date range parameter

I have a report in SSRS 2016 that contains one SP which has a date field called startdate. I'd like to create a parameter where the user can select between two ranges: startdate >='2017'or startdate < '2017'. This seems like it should be simple, but I can't see to find an easy way to do this.
I've tried to create a parameter in SSRS where I chose "Specify Values" and manually added these values but I get an error that the "expression references the parameter "startdate" which does not exist in the Parameters collection.
I'm sure I can create this by creating a stored procedure with these dates, but that seems like more work than is needed.
Does anyone know of a better way to do this?
If you are looking to have a parameter that has two options, 0 - Before 2017, and 1 - After 2017 then you should just create a Date parameter which has two options, Before 1/1/2017 in the label field with a 0 in the value field and After 1/1/17 in the label field with a 1 in the value field. Then in your report you just have to filter your data based upon the 1 or 0 value.
For example:
DECLARE #DateFilter INT = 1
IF ( #DateFilter = 0 )
BEGIN
SELECT * FROM dbo.MyTable t
WHERE t.DateFilter < '1/1/17'
END
IF ( #DateFilter = 1 )
BEGIN
SELECT * FROM dbo.MyTable t
WHERE t.DateFilter >='1/1/17'
END
I don't know why you would filter your data this way. I recommend to use Larnu's suggestion that you have two parameters, a Start Date and an End Date. Otherwise this could return a lot of rows for the second option as time goes on.
Add a couple of parameters in SSRS say, FromDate and ToDate and make its data type as Date/Time.
You can specify the default values for these parameters using DateAdd functions and samples give below:
Today:
=Today()
last week from today:
=DateAdd(DateInterval.Day, -7,Today())
You can add/reduce year, quarter month etc. in a similar way as shown below. Just change the number to the required length
=DateAdd(DateInterval.Year,-1,Today())
=DateAdd(DateInterval.Quarter,-1,Today())
=DateAdd(DateInterval.Month,-1,Today())
=DateAdd(DateInterval.DayOfYear,-1,Today())
=DateAdd(DateInterval.WeekOfYear,-1,Today())
=DateAdd(DateInterval.WeekDay,-1,Today())
=DateAdd(DateInterval.Hour,-1,Today())
=DateAdd(DateInterval.Minute,-1,Today())
=DateAdd(DateInterval.Second,-1,Today())

What should be a default datetime value?

I am inserting Excel Sheet records in my DataTable in c# and passing this DataTable to an SQL stored procedure. In my c# code I have put certain checks for empty data cells of Excel sheet to avoid Exceptions. But It seems like I am missing something while giving a default value for my SQL Date field.
string InvoiceDate = (row.Cells[3].Text == " ") ? "0/00/0000 00:00:00 AM" : (row.Cells[3].Text);
And I get the following error:
String was not recognized as a valid DateTime.Couldn't store
<0/00/0000 00:00:00 AM> in InvoiceDate Column. Expected type is
DateTime.
Edited -
Declaration of SQL field [InvoiceDate]
[InvoiceDate] [date] NOT NULL
Please don't suggest inserting null as I cannot Insert null for this column.
First, There is no 00/00/0000 date, not in the real world and not in sql server.
Second, why do you even need a default values? just use null instead.
Third, use ISO 8601 format for specifying dates in strings (yyyy-mm-ddThh:mm:ss)
Forth, As Giorgi rightfully pointed out in his comment, why even use strings for a datetime value? use a variable of type DateTime in c#. note that it's min value is different then the sql server DateTime data type min value.
If your datetime column is not nullable, you can use 1753-01-01 (min value for datetime) or 9999-12-31 (max value for datetime)
One last thing, you might want to consider using either datetime2 or separate the date and time to different columns (data types date and time, of course). Why? read here.
Try to insert the current date instead:
string InvoiceDate = string.IsNullOrEmpty(row.Cells[3].Text) ? DateTime.Now.ToString() : (row.Cells[3].Text);

Allow Search for Invalid Date stored as string - Is it recommended or not

I have two tables for an Entity - say Valid_Doc and Invalid_Doc. If document is valid, then all the data gets saved in Valid_Doc table.In case any of the attribute of document is invalid , it gets saved in Invalid_Doc.Due_Date is on of the column of both the tables. In Invalid_Doc , we are saving Invalid dates as string.
Suppose if user searches for documents through a SEARCH screen with following date
Due_Date - is after - 07/07/11,
Shall we show all the documents from both the tables.As Due_Date in Invalid_Doc table is string, there is no way we can compare the entered search date with the dates available in database in Invalid_Doc table.
Can someone please guide me whether to use DATEDIFF - i.e. need to convert the String date in DB to Date(millisecs) first and then do the comparison with the entered data.Doing this , there may be unpredictable results. So , shall we allow the user to search for Invalid doc through Date or NOT.
Select * FROM invalid_doc iil WITH (nolock) WHERE
CAST(Datediff(s, '19700101 05:00:00:000', iil.due_date) AS NUMERIC) *
1000
BETWEEN '1120501800000' AND '1120501800000'
Where '1120501800000' and '1120501800000' are Date converted in milliseconds.
Please suggest.
I would convert the dates in the database to a uniform string format using regex (eg. Q20011231Q) and also convert the query to the same format before searching.
This way you would have control on your data and can easily do comparisons
I continue as answer :)
As I don't know your language you handle the xml data I strongly suggest you validate you date befor you insert into your database.
It is not possible to enter a non valid data value into a datatime field.
if you have a data like 11/24/2011 and insert it, the datetime value always add the time itself.
Then you have eg. 11/24/20011 17:29:00 000 as value stored.
If you insert less then a date it might crash or if the value can be converted to a valid date, the missing parts will be replaced by "current date information".
So in fact you have to validate you string, convert it. Something like this:
-- #datestring <= somehow your string from xml
SET arithabort arith_overflow OFF
SET #date = CAST(#datestring AS DATETIME)
IF #date is NULL SET #date = GETDATE()
SET arithabort arith_overflow ON
You turn overflow error mode off, try convert and set default if it fails.
Or in MS SQL
IF ( ISDATE(#date_string) = 0 ) SET #date = GETDATE()
Hope this helps

Resources