Using CAST or CONVERT inside a view MSSQL - sql-server

Hi Having a syntax issue - at least I think it is. I want a default date as part of a case statement inside a materialised view (MS SQL 2008 +):
, CASE
WHEN WithFirstDate = 0 THEN CONVERT(DATE,'1900-JAN-1', 101)
WHEN WithFirstDate = 1 THEN
Start1
ELSE --WithFirstDate = 2
Start2
END ValidDate
I'm getting the following error:
view uses an implicit conversion from string to datetime or smalldatetime. Use an explicit CONVERT with a deterministic style value
I'd like to have a solution that works irrespective of localization (i.e US style dates, Japanese style dates and the rest of the world)
Thanks

Instead of:
CONVERT(DATE,'1900-JAN-1', 101)
Just do:
CONVERT(DATE,'1900-01-01')
However the issue may be with the other two columns, Start1 and Start2. I am guessing these are not DATE columns.

The 101 code you are passing the CONVERT function does not match your format. Check the following link to find the correct code:
http://msdn.microsoft.com/en-us/library/ms187928.aspx

Ok well this forum has gone downhill IMHO, first my post get endless edited for grammar which doesn't change the meaning, then it gets voted down presumably because it was "to difficult" to answer. https://stackoverflow.com/users/61305/aaron-bertrand was on the right lines. Thanks Aaron. The problem was a computed column in one of the referenced tables was non deterministic. This error only resolved in a flag when the materialising clustered index was being created on the view. I'd post a link to the full answer but not allowed. Shame I cant recover all my old badges and points from a couple of years ago. Full answer here http://tinyurl.com/knor8qk

Related

Replace is not working for weird character

I use UPDATE a SET GR_P = REPLACE(GR_P,'','') FROM mytable a to replace things.
But replace function is not working for below charter:
In Query analyzer it works but when I used SSIS Execute SQL task or OLEDB Source then it is giving me error:
No Connection manager is specified.
In Toad against Oracle (since that's one of your tags), I issued this (pressing ALT-12 to get the female symbol) and got 191 as a result. note selecting it back using CHR(191) shows an upside-down question mark though.
select ascii('♀') from dual;
Given that, this worked but it's Oracle syntax, your mileage may vary.
UPDATE mytable SET GR_P = REPLACE(GR_P, CHR(191));
Note if it does not work, that symbol could be for another control character. You may need to use a regular expression to eliminate all characters not in a-zA-Z0-9, etc. I suspect you'll need to update your tags to get a more accurate answer.
Maybe this info will help anyway. Please post back what you find out.

Convert varchar dd-mm-yyyy to yyyy-mm-dd date field in SQL Server 2008

hopefully the title describes what I'm trying to do.
I have a varchar field in a SQL Server 2008 table that contains text dates in the format dd-mm-yyyy (e.g., 31-12-2009). I am trying to use CONVERT to convert it to a DATE field. I was successful in converting a similar varchar field in the same table using the following:
SELECT DISTINCT(CONVERT(DATE, MYDATEFIELD1, 103)) AS [CONV_MYDATEFIELD1] FROM MYTABLE;
But when I apply the same to MYDATEFIELD2, which appears to have the same type of data values as MYDATEFIELD1, it fails with the following error:
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
I've tried sorting and using LIKE to try to find any characters that might prevent the conversion but I haven't been able to pinpoint anything.
Any help will be greatly appreciated. Thanks!
You may have some invalid dates (e.g. 30-02-2009), try to find them splitting the characters and validating the day and the months, assuring that the days correspond to the month and the month is in the range 01 - 12.
If you can't find which value is causing the conversion error then use a cursor to go through all the records individually and use TRY CATCH to find which record(s) cause the conversion error. You could use a PRINT statement in the CATCH block to identify the records that are erroring.
Find your bad dates with the following:
SET DATEFORMAT dmy;
select MYDATEFIELD1, isdate(MYDATEFIELD1)
from MYDATEFIELD1
I figured out the issue that was causing the CONVERT to fail but I'm not sure of the best way to select an answer (veritable stack noob) so, any help on that would be appreciated. Here are the major steps I took to find the issue:
I used MIN and MAX SUBSTRING to identify that the component parts of the
varchar field were correct (i.e., the 1st two digits min=01 max=31,
middle two min=01 max=12)
I used DISTINCT SUBSTRING to identify that all of the date separators were consistent (i.e., all dashes).
I used MAX(LEN) to determine that my varchar "date" field was 12 characters (vs. the 10 characters I was expecting).
I used CONVERT(VARBINARY, MYDATEFIELD2) to determine what was actually stored in the string.
The last step revealed that the field contained line feeds (00A). I opened the source text file in notepad++, clicked View -> Show Symbol -> Show All Characters and I could see the LF at the end of each line.
So now I'm modifying the DTSX package (fixed width text) to include an extra field for the linefeed that I can drop afterwards. Now that I know what the intended format of the date fields is, I'll try to import them as DT_DATE vs DT_STR. I'm not exactly sure how to specify the correct date style 105 at import (thanks #Panagiotis Kanavos) but I'll figure it out.
Whew! What a learning experience! :D
Thanks to everyone who helped - and if you can give advice on the best way to select the best answer it will be greatly appreciated.

Hacked SQL Server database need regex

A database that a client of mine has was hacked. I am in the process of trying to rebuild the data. The site is running classic ASP with a SQL Server database. I believe I have found where the weak point was for the hackers and removed that entry point for now.
Every text colummn in the database was appended with some html markup and inline script/js tags.
Here is an example of a field:
all</title><script>
document.write("<style>.aq21{position:absolute;clip:rect(436px,auto,auto,436px);}</style>");
</script>
<div class=aq21>
<a href=http://samedaypaydayloansonlineelqmt.com >same day payday loans online</a>
<a href=http://samedaypaydayloan
This example was in the Users table in the UserRights column. The initial value was all, but then you can see the links that were appended.
I need to write a regex script that will search through all fields in each column of each table in the database and remove this extra markup.
Essentially, if I try to match </table>, then that string and everything that appends it can be replaced with a blank string.
All of these appended strings are the same for each field in the same column. However, there are multiple columns in each table.
This is what I have been doing so far, replacing the hacked part, but a nice regex would probably help me out, though my regex skills.... well suck.
UPDATE [databasename.[db].[databasetable]
set
UserRights = replace(UserRights,'</title><script>document.write("<style>.aq21{position:absolute;clip:rect(436px,auto,auto,436px);}</style>");</script><div class=aq21><a href=http://samedaypaydayloansonlineelqmt.com >same day payday loans online</a><a href=http://samedaypaydayloan','');
Any regex help and/or tips are appreciated.
This is what I ended up doing (big thanks to #Bohemian):
I went through each table and checked which column was affected. Then I ran the following script on each column:
UPDATE [tablename]
set columnname = substring(columnname, 1, charindex('/', columnname)-1)
where columnname like '%</%';
If the column had any markup in it, then I ended up manually updating those records manually. (lucky for me there was only a couple of records).
If anyone has any better solutions, please feel free to comment.
Thanks!
Since the bad stuff starts with a <, and that is an unusual character to typically find, I would use normal text functions, something like this:
update mytable set
mycol = substr(mycol, 1, charindex('<', mycol) - 1)
where mycol like '%<%';
And methodically do this with every column of every table.
Note that I'm only guessing at the right function to use, since I'm unfamiliar with SQL Server, but you get idea.
I welcome someone editing the SQL to improve it.

SQL Reporting Services 2005 - Non-queried Report Parameters

I'm working on a report in Reporting Services and I can't figure out why I'm having trouble with Non-queried report parameters.
I'm trying to get the current year and have tried:
=YEAR(TODAY())
=DATEPART("yyyy",TODAY())
I have also tried TODAY instead of TODAY()
All of these seem to break the Year dropdown on my report. I thought if something was wrong it would just not get the correct default... but nope, it breaks the whole field.
Any thoughts? articles?
UPDATE:
Wait, wait, wait... the weirdest thing. The Year parameter is the second parameter of this report. And its grayed out (with no value) UNTIL I select the first parameter (im my case "category"). Am I somehow telling the Year param to do this? or does SSRS 2005 process the params in order? I don't think I ever noticed this before.
UPDATE 2:
Please see all comments
=DateTime.Today.Year
should work as well.
Edit: Bruno - i have the same behavior as you are seeing. I created a sample report with a string first parameter with no default value, and a string 2nd parameter with a default of =DateTime.Today.Year. When I have the one with the default as the 2nd parameter in the order, it shows up empty and disabled.
I was able to fix this problem 2 ways: first by adding a default of =String.Empty to my first parameter, and the second way was to just change the order of the parameters.
Not sure if this behavior is by design or a bug - but like you said, I hadn't noticed it either until today when you pointed it out in your question.
Try:
=Year(Now)
I'm not sure if this is what you need, but it worked for me. I used it to form a date string so I used =Year(Now).ToString().
SSRS does process the report parameters in order - order can be important if you have dependencies between your parameters.
From MSDN: "Parameter order is
important when you have cascading
parameters, or when you want to show
users the default value for one
parameter before they choose values
for other parameters."
So, it will always wait until you have a default value for your first parameter or you enter the first parameter's value, before it processes the next one, and so on.
http://msdn.microsoft.com/en-us/library/cc281392.aspx
I found the by making sure that ALL of my parameters had at least some default value, then you will not experience they greyed out datetime picker. So, every parameter before your datetime paremeter in order needs to have a (default) value or it will not work.
Def due to order of evaluation of parameters.
Simple workaround ; in the parameters tab you can change the order of the parameters - this will move the date pickers to the top of the list and are then enabled straight away, on my server at least.
Someone raised the issue of basing a date filter on a queried default value - if you do this, you will notice a very annoying knock-on effect of getting screen refresh any time the dates get changed, before you have a chance to requery the reports.

How do I get rid of .. Replace(Replace(Replace(Replace(Replace( …?

I’m selecting data on an old database which has an abused status column. The status column has multiple pieces of information in it. Values are like ‘New Contact YYYY’, ‘Online YYYY’, ‘Updated YYYY’, ‘Withdrawn YYYY’, etc…. As you may have guessed, YYYY represents the year … which I need.
In the past I’ve done something similar to
Rtrim( ltrim( Replace(Replace(Replace(Replace(Replace( …
Basically, replacing all text values with an empty string, so the only thing that still exists is the year. I can still do this, but I’m thinking this is ridiculous, and there’s got to be a better way.
Does anybody know of a better way to do this?
If you simply want to extract a four digit year from the string, you could use PATINDEX
SELECT SUBSTRING(FieldName, PATINDEX('%[0-9][0-9][0-9][0-9]%', FieldName), 4)
FROM TableName
If the year allways are the last 4:
SELECT right(FieldName,4) from table
All the answers given solve your problem, but the correct answer is to normalize your data base better. If you need the year as a separate item, it should be stored in a separate column.
Anything else is just removing hairs from a wart, as my dear old grandma used to say (she never actually said that, I just thought of it and it sounded kind of cool - must be why I don't get out much :-).

Resources