SQL Server, VS 2019 Winforms, ReportViewer.
This doesn't work in straight SQL either, so I'll start there.
I have a query that looks like this:
declare #d1 Date, #d2 date, #SalesRep nvarchar(20), #customer nvarchar(300), #stype nvarchar(10)
set #d1 = '01 oct 2021'
set #d2 = getdate()
set #SalesRep = ''
set #customer = ''''',''A'',''B'',''C'',''D'',''E'',''F'',''G'',''H'',''I'''
set #sType=null
select #customer
select
vss.Customer, vss.Invoice_No, vss.Salesman,
vss.Invoice_Date, vss.Total_Amount, vss.Description
from
v_SaleSum vss
where
vss.Invoice_Date between #d1 and #d2
and ((ISNULL(#SalesRep,'') = '') OR (vss.Salesman = #SalesRep))
**and (Customer in (#customer))**
and [dbo].[Invoice_sType] (vss.Invoice_No, #sType)=1
Order by
vss.Invoice_No
You can see the crux of the issue here.
The #customer param needs to be a list. But if you comma separate it, as I have the query looks for customers that match the whole comma separated list as one string, not as a list of strings.
I do not have the option of modifying the SQL at runtime because of the whole Dataset, BindingSource, TableAdapter setup.
What am I missing here? There must be some way to add a list of values to a parameter.
--Update:
Here's why I can't use Table-Value Parameters:
There is no "Table" parameter type supported.
I found that I could do this:
... and (#customer like ('%'''+ Customer+'''%'))
Since the match string is in the format '''A'',''B''' (or more simply without having to escape the tick marks, ' 'A','B' '
searching for the customer name to exist in the parameter seems kind of backwards, but its working.
This way, I check if %'A'% is like 'A','B','C'
Related
I can successfully use a Query with a Date parameter in string format as
SELECT * FROM ORDERS WHERE [DATE]='20160209'
but I haven't seen any sample of a Query specifying a DateTime parameter in string format.
Next samples are rejected by Microsoft SQL Server Management Studio:
SELECT * FROM ORDERS WHERE [DATE]='20130523T153500000Z'
SELECT * FROM ORDERS WHERE [DATE]='2013-05-23T15:35:00:000Z'
I know this is not a good practice and I should pass DateTime values rather than strings, but sometimes it is useful for debugging.
What is the right format to include a string formatted datetime on a SQL query?
No so sure where you've got those date formats...
This one '2013-05-23T15:35:00:000Z' just doesn't seem to be right. I haven't seen that nanoseconds were delimited by a ':' character. It is usually a decimal of a second, so '2013-05-23T15:35:00.000Z' is a better format and it works:
select convert(DateTime,'2013-05-23T15:35:00.000Z')
As for the other, you might need to do the parsing yourself:
select CONVERT(DATETIME,LEFT('20130523T153500000Z',4)+SUBSTRING('20130523T153500000Z',5,2)+SUBSTRING('20130523T153500000Z',7,2))
hope this helps.
Can you just do something like this?
SELECT *
FROM ORDERS
WHERE [DATE] = CONVERT(DATETIME,'20130523T153500000Z')
As long as the string is in a workable format.
If it's just for debugging, you might do something like:
DECLARE #val VARCHAR(25)
-- Easily swapped out with different testing values
SET #val = '20130523T153500000Z'
SELECT *
FROM Orders
WHERE [DATE] = CAST(#val AS DATETIME)
-- You could also use CONVERT
I have a stored procedure which takes in dates in a variety of formats and converts them to datetimes. The following line works just as expected:
RETURN CONVERT(datetime,#vMonth+'/'+#vDay+'/'+#vYear)
However, I want to specify that the date should always be treated as being in US format, as this will return the wrong result if T-SQL is set to use British. If I do this:
RETURN CONVERT(datetime,#vMonth+'/'+#vDay+'/'+#vYear, 101)
Then I start getting the following error (on all values I've tried):
Conversion failed when converting date and/or time from character string.
I've done a search and none of the threads that mention this error seem to be the same problem. I'm confused as to why specifying us_english (101) for a string that's already being converted as us_english causes the procedure to break.
Edit: I've boiled this down to a minimum case that shows where I'm not understanding.
This works:
select CONVERT(datetime,'01/02/03')
This does not:
select CONVERT(datetime,'01/02/03',101)
This works fine for me. No errors.
declare #mydate datetime = getdate()
declare #vMonth varchar(10), #vDay varchar(10), #vYear varchar(10)
set #vMonth = cast(DATEPART(mm, #mydate) as varchar(10))
set #vDay = cast(DATEPART(dd, #mydate) as varchar(10))
set #vYear = cast(DATEPART(YYYY, #mydate) as varchar(10))
select CONVERT(datetime, #vMonth+'/'+#vDay+'/'+#vYear, 101)
Result:
2015-01-09 00:00:00.000
It turns out that when using 101 as the language, SQL Server expects the century to be in XXXX format. To handle 2-digit years correctly, you must use 1 as the language instead.
Disclaimer: I am still learning SQL so I apologize if my question comes off as amateur-ish or is otherwise a very simple answer. I have no formal training. I am teaching myself. Thanks.
A particular query was created to update the EMAIL column with data in the EMAIL2 column should the EMAIL column be blank. This query goes on to grab data from the EMAIL3-6 columns should any prior ones also be blank in an attempt to populate the EMAIL column. It currently sits as follows:
update Parents
set email = email2
where email = ' ' OR email is null
go
update Parents
set email = email3
where email = ' ' OR email is null
go
update Parents
set email = email6
where email = ' ' OR email is null
go
(and so on)
Is there a more simple way, using some sort of IF...THEN type conditions to check for blank or null in the EMAIL column and populate it based on data in the secondary column(s)? These columns would also need to be checked for blank or null values and skipped if blank or null is true.
I appreciate any advice that can be given. The above query works it just doesn't feel like the best way to go about doing it.
A handy function you will want to become aquainted with is NULLIF. It allows you to simplify your logic in cases where you might like to treat a value like a NULL. For example, if an application was putting a sentinel value of 'NA' in a NULLable column column1, NULLIF(column1, 'NA') would return the NULL value for all the NULLs and all the NAs. In your case, we'd use this trick to convert empty strings into NULLs.
The other thing we'll do is trim all the empty strings down so our NULLIF only needs to check for the scenario of '' (instead of '', ' ', ' ', ad nauseum). TSQL only provides LTRIM and RTRIM and I have a habit of using RTRIM although trimming an empty string from either direction will result in our desired state. NULLIF(RTRIM(column1),'')
Using that expression, we will now have the right thing to plug into the COALESCE function. Thus
UPDATE
P
SET
email = COALESCE(NULLIF(RTRIM(P.email2), ''), NULLIF(RTRIM(P.email3), ''), NULLIF(RTRIM(P.email4), ''))
FROM
dbo.Parents P
WHERE
-- This will force a table scan which can be a bad thing for performance
-- Generally, one should avoid wrapping functions around a column and instead
-- apply them to the thing being tested
NULLIF(RTRIM(P.email), '') IS NULL
Do you mean something like this?
update Parents
set email = COALESCE(
NULLIF(LTRIM(RTRIM(email2), '')),
NULLIF(LTRIM(RTRIM(email3), '')),
NULLIF(LTRIM(RTRIM(email4), '')),
NULLIF(LTRIM(RTRIM(email5), '')),
NULLIF(LTRIM(RTRIM(email6), ''))
)
where email = ' ' OR email is null
The
LTRIM(RTRIM(email2)
will make sure the convert ' ' to an empty string '', since SQL Server has no trim, but two separate functions LTRIM and RTRIM. NULLIF returns null if the two expressions are equal.
So if any of the email cols is null or just ' ' it will return null.
The COALESCE function will return the value of the first expression, that is not null.
Not to make this a tutorial on COALESCE and NULLIF but to proof everything #billinkc provided in his answer, this is why that works. (Sorry I was working on the solution as he answered it). Plop this into SSMS and have a look at the results. A simple update like shown above will do nicely though.
Just Discovered the SQL Fiddle Resource:
SQL Fiddle
--Setup the temp table
DECLARE #Parents TABLE (
ParentsId INT IDENTITY (1,1) PRIMARY KEY,
email varchar(max),
email2 varchar(max),
email3 varchar(max),
email4 varchar(max),
email5 varchar(max),
email6 varchar(max)
)
--This would be the pull from your real Parents Table.
INSERT INTO #Parents
SELECT
NULL,'test#domain.com',' ',NULL,NULL,NULL
UNION ALL
SELECT
NULL,' ',NULL,NULL,NULL,'test2#domain.com'
UNION ALL
SELECT
NULL,'',NULL,NULL,NULL,'test3#domain.com'
--Look at the data before we cleanse it
SELECT * FROM #Parents
--Take a look at what COALESCE looks like before the cleanse
SELECT ParentsId, COALESCE(email2,email3,email4,email5,email6) AS NewEmail FROM #Parents
--RUN the NULLIF
UPDATE #Parents SET
email2 = NULLIF(email2,' '),
email3 = NULLIF(email3,' '),
email4 = NULLIF(email4,' '),
email5 = NULLIF(email5,' '),
email6 = NULLIF(email6,' ')
SELECT * FROM #Parents
--Take a look at what COALESCE looks like after the cleanse
SELECT ParentsId, COALESCE(email2,email3,email4,email5,email6) AS NewEmail FROM #Parents
I'm trying to transfer some old SQL Server data using Excel into SQL Server. It seems that Import/Export Data application automatically sets most data columns to NVARCHAR(255). Problem I have, is one of my columns is supposed to be a DATE type, but all data in it looks like this 18.08.2000 14:48:15.
So, when I try to use this query:
SELECT CONVERT(Date, DATE_TIME, 113)
FROM someTable
I get this error:
Msg 9807, Level 16, State 0, Line 1
The input character string does not follow style 113, either change the input character string or use a different style.
None of the [styles] from CAST and CONVERT (Transact-SQL) are working in my case.
Any advise or help is greatly appreciated.
SOLVED:
UPDATE myTable
SET columnName = CONVERT(NVARCHAR(255),CONVERT(SMALLDATETIME, columnName,105))
ALTER TABLE myTable
ALTER COLUMN columnName SMALLDATETIME
So, if it will ever become useful to anyone, this is the exact code that changes datatype NVARCHAR to DATETIME:
UPDATE myTable
SET columnName = CONVERT(NVARCHAR(255),CONVERT(SMALLDATETIME, columnName,105))
ALTER TABLE myTable
ALTER COLUMN columnName SMALLDATETIME
As far as I can tell - style no. 103 (British/French) should work - no?
DECLARE #input NVARCHAR(255)
SET #input = '18.08.2000 14:48:15'
SELECT CONVERT(DATETIME, #input, 103)
Gives me the output of:
2000-08-18 14:48:15.000
which seems pretty reasonable, no??
If you are using SQL Server 2012, try:
PARSE(Date AS datetime USING 'en-GB')
Or if that doesn't work, try:
PARSE(Date AS datetime USING 'Et-EE')
The Estonian culture specifically uses '.' as a date separator (d.MM.yyyy H:mm:ss) so it should work.
(Both seem to work fine on SQL Fiddle)
I have a row entry with the following format:
Site=[number];this=that;foo=bar;
[number] above can be from 1...infinity. So I need to split out the [number] to use in another select statements where clause. Site=[number] is always at the beginning in the string and the data is always separated by a semi-colon.
declare #t nvarchar(100) = 'Site=230;this=that;foo=bar;';
select convert(int, substring(#t,6, charindex(';',#t,0)-6))
SELECT SUBSTRING(col, 1, CHARINDEX(col,';'))
Why are you storing data in the database in this format? Split it up into columns so that you can do meaningful queries.
You can play with the string this way:
declare #tx as nvarchar(100)
set #tx = 'Site=[number];this=that;foo=bar;'
print substring(
#tx,
CHARINDEX('[', #tx)+1,
CHARINDEX(']',#tx)-CHARINDEX('[',#tx)-1)
Hope this helps.
I don't have MS Sql Server available to try this out, but have you tried something like
Select
field
convert(bigint, substring(field, 6)) as thenum
from
thetable
where
condition=something
where field is the name of the field containing site=[number];...
The theory goes that substring will strip off site= off the beginning, and convert
will (hopefully) convert the number portion and ignore the rest of the text from the semicolon onwards.
It may or may not work. If not you may need to write an elaborate function instead.