Changing query from access SQL to SQL server - sql

I created this query in Microsoft access and I am trying to run it in SQL Server 2012 but I am getting several errors I have tried a few different ways to fix it but I still cant get it working
SELECT Choose(Iif(IsNull([TaxCodeChangeTypeID]),0,
[TaxCodeChangeTypeID])+1,
'UNKNOWN',
'UPLIFT',
'PAPERP6',
'PAPERP9',
'P453',
'P46',
'HMRC',
'DPSP6',
'DPSP9',
'P46(Pen)',
'P46(Expat)') AS [Tax Code Change Type]
FROM EeBals

As mentioned in comments, ISNULL in Access takes a single parameter and returns a boolean value depending on whether the parameter passed is null, in SQL Server ISNULL takes two arguments, the first is the value to check, and the second is the value to return if the value is null, so your line:
Iif(IsNull([TaxCodeChangeTypeID]),0, [TaxCodeChangeTypeID])+1
Needs to be replaced with
ISNULL([TaxCodeChangeTypeID], 0) + 1
To acheive the same thing. Making your full query:
SELECT CHOOSE(ISNULL([TaxCodeChangeTypeID], 0) + 1,
'UNKNOWN',
'UPLIFT',
'PAPERP6',
'PAPERP9',
'P453',
'P46',
'HMRC',
'DPSP6',
'DPSP9',
'P46(Pen)',
'P46(Expat)') AS [Tax Code Change Type]
FROM EeBals

Not being able to test it, but as it seems ISNULL should be the only issue here.
In MS Access, ISNULL returns true if the checked value is in fact null, but in SQL Server it works like a COALESCE (but only taking 2 instead of unlimited parameters) returning the second value if the first was null.
CHOOSE and Iif should work similarily to MS Access in SQL Server.
I would simply replace IsNull([TaxCodeChangeTypeID]) with [TaxCodeChangeTypeID] IS NULL
SELECT Choose
(
Iif
(
[TaxCodeChangeTypeID] IS NULL,
0,
[TaxCodeChangeTypeID]
)+1,
'UNKNOWN','UPLIFT','PAPERP6','PAPERP9','P453','P46','HMRC','DPSP6','DPSP9','P46(Pen)','P46(Expat)'
) AS [Tax Code Change Type]
FROM EeBals
Note: this only applies to SQL Server since the version 2012, before that neither IIF nor CHOOSE were present in either standard SQL Server or SQL Server Express
PS: of course the whole IIf(...)+1 can now be avoided and be a little more beautified as GarethD also mentioned in his post by writing ISNULL([TaxCodeChangeTypeID], 0) + 1 instead.

Related

Power function Sql only 3dp

select power(1.005,4) [Power]
gives 1.020
select 1.005*1.005*1.005*1.005 [Manual]
gives 1.020150500625
i need the latter result but don't want to do manually. 4th Power in this case but will be variable.
please advise. thanks
Based on your syntax, I assume you are using SQL Server. As explained in the documentation for power():
Returns the same type as submitted in float_expression. For example,
if a decimal(2,0) is submitted as float_expression, the result
returned is decimal(2,0).
SQL Server interpets numeric inputs as decimals, not floats. So, if you want the full value, convert the value before calling the function:
select power(convert(float, 1.005), 4) as [Power]
Here is a Rextester comparing the different approaches.

Access SQL Date Function

So I'm working on editing some SQL code and I've just began learning it. I'm trying to fix an update query so it updates a table's value5 column with a corresponding database value. The value type from the database is a number, which I want to convert to a date and place into my table. The database number is in yyyymmdd format so I've been trying to use datefromparts() which doesn't work. Anyone have any ideas?
UPDATE tbl INNER JOIN dB ON
(dB.value1= tbl.value1 OR
dB.value2 =tbl.value2 ) AND
(LEFT(dB.value3 ,5)=tbl.value3 ) AND
(dB.value4 =tbl.value4 )
SET tbl.value5 = DateFromParts(Left(dB.value5,4),Mid(dB.value5,5,2),Right(dB.value5,2))
WHERE tblInvoice.value5 IS NULL;
The current program uses the code
"SET tbl.value5 = dB.value5"
instead (it runs perfectly fine) and I am having another issue with testing the conversion SQL code (datefromparts()). Because I am converting from numbers to time/date, I have to go into the design view of the target table and change the input data type of the value5 column from numbers to time/date. When I run the query with the conversion SQL code, the query stalls for a bit and no values get updated, leaving me with just a blank value5 column. If I now want to fill in the original number values, I change the SQL code back into its original "SET tbl.value5 = dB.value5", change the input data type from time/date to numbers, and rerun the program. The query stalls and no values are updated, and I am again left with blank columns, even though the same code left me with the corrected update values before the modifications to the SQL and table input Data types. I come from a VBA background and I'm just really confused with how this is working. Any tips would be appreciated, thanks!
Have you tried with substring instead?
SELECT DATEFROMPARTS ( left('20101231',4), substring('20101231',5,2), right('20101231',2) ) AS Result;
MS Access (and MS Jet too) have no DateFromParts function. Using DateSerial instead.
SET tbl.value5 = DateSerial(Left(dB.value5, 4), Mid(dB.value5, 5, 2), Right(dB.value5, 2))
It's not clear if you work with T-SQL or Access SQL. In Access, you can use Format:
SET tbl.value5 = CDate(Format(dB.value5, "####\/##\/##"))
In T-SQL you could use a similar method.

converted data type (varchar) still shows conversion error

I have a column that can store text but is used to store a number (I did not make the system!) someone has put a blank value in (i.e. not content but not null) and its causing error: -
Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar to numeric.
I have reduced the issue down to the below: -
SELECT
T1.[FIELD_5],
ISNUMERIC(T1.[FIELD_5]),
NULLIF(T1.[FIELD_5],''),
ISNULL(NULLIF(T1.[FIELD_5],''),0),
CONVERT(DECIMAL(18,5),ISNULL(NULLIF(T1.[FIELD_5],''),0))
FROM
[MyTBL] T1
ORDER BY
ISNUMERIC(T1.[FIELD_5])
The issue data is in [FIELD_5]
I can see SQL sees a value as not numeric
I can see that NULLIF is successfully changing it to a NULL value
I can see the ISNULL is turning the NULLIF result to 0
But the CONVERT on the ISNULL result results in the error message, I would expect it to result in 0.00000
Use try_convert():
SELECT T1.[FIELD_5], ISNUMERIC(T1.[FIELD_5]), NULLIF(T1.[FIELD_5], ''),
COALESCE(NULLIF(T1.[FIELD_5], ''), 0),
TRY_CONVERT(DECIMAL(18, 5), COALESCE(NULLIF(T1.[FIELD_5], ''), 0))
FROM [MyTBL] T1
ORDER BY ISNUMERIC(T1.[FIELD_5]);
try_convert() was introduced in SQL Server 2012. If you are using an earlier version, then you need to use a case expression.
(I switched ISNULL() to COALESCE() because I prefer to use ANSI standard functions where practical.)
There is some non numeric value available you can do that check with case as below:
select convert(decimal(18,5), '')
Throws error as "Error converting data type varchar to numeric.
"
SELECT
T1.[FIELD_5],
ISNUMERIC(T1.[FIELD_5]),
NULLIF(T1.[FIELD_5],''),
ISNULL(NULLIF(T1.[FIELD_5],''),0),
CONVERT(DECIMAL(18,5), iif(isnumeric(ISNULL(T1.[FIELD_5]),'0') > 1,T1.[FIELD_5],'0')
ISNULL(NULLIF(T1.[FIELD_5],''),0))
FROM
[MyTBL] T1
ORDER BY
ISNUMERIC(T1.[FIELD_5])
This was a case of better investigation was needed, I should have realised as in my opinion SQL doesn't lie its normally always user error.
I run it again without the order by clause and then selected the row that would have shown up after the last row that did show up (i.e. that row that caused the error).
[FIELD_5] contained the value 1E-07, an infamous bad import from Excel!
What doesn't add up is why when I had the order by ISNUMERIC on, I did not see this value at the top of the list, only the blank values that were indeed being managed properly.
Question solved, I should have stuck investigating but I think this is worth leaving up to help other investigate in the future.

SQL Select to keep out fields that are NULL

I am trying to connect a Filemaker DB to Firebird SQL DB in both ways import to FM and export back to Firebird DB.
So far it works using the MBS Plug-in but FM 13 Pro canot handle NULL.
That means that for example Timestamp fields that are empty (NULL) produce a "0" value.
Thats means in Time something like 01.01.1889 00:00:00.
So my idea was to simply ignore fields containing NULL.
But here my poor knowlege stops.
First I thought I can do this with WHERE, but this is ignoring whole records sets:
SELECT * FROM TABLE WHERE FIELD IS NOT NULL
Also I tried to filter it later on like this:
If (IsEmpty (MBS("SQL.GetFieldAsDateTime"; $command; "FIELD") ) = 0 ; MBS("SQL.GetFieldAsDateTime"; $command; "FIELD"))
With no result either.
This is a direct answer to halfbit's suggestion, which is correct but not for this SQL dialect. In a query to provide a replacement value when a field is NULL you need to use COALESCE(x,y). Where if X is null, Y will be used, and if Y is null then the field is NULL. Thats why it is common for me to use it like COALESCE(table.field,'') such that a constant is always outputted if table.field happens to be NULL.
select COALESCE(null,'Hello') as stackoverflow from rdb$database
You can use COALESCE() for more than two arguments, I just used two for conciseness.
I dont know the special SQL dialect, but
SELECT field1, field2, value(field, 0), ...FROM TABLE
should help you:
value gives the first argument, ie, your field if it is NOT NULL or the second argument if it is.

Wrong number of arguments with SQL ISNULL() on Access DB

I have this query in VB application on Access DB:
SELECT DISTINCT Specialization, MAX(a.faultZone) AS faultZone, ISNULL(a.faultCount, 0) AS NoOfFaults FROM Technicians AS t
LEFT JOIN
(
SELECT DISTINCT Faults.[Type] AS faultType, MAX(Faults.[Zone]) AS faultZone, COUNT(Faults.[Type]) AS faultCount
FROM Faults "
WHERE Faults.[Zone] = 8 " ' this value will be from variable
GROUP BY Faults.[Type] "
) AS a
ON (t.Specialization = a.faultType)
WHERE t.specialization <> 'None' "
GROUP BY a.faultCount, t.Specialization
It gives following problem that I can't solve...
"Wrong number of arguments used with function in query expression
'ISNULL(a.faultCount, 0'."
What I want to achieve is simply set value of NoOFFaults to zero, which would mean there are no faults in particular Zone.
Thank You
Just to add my two cents, and while I like the simple syntax of Nz(), if you seek trouble free performance, both IsNull() and NZ() should be avoided in favor of Is Null:
IIF(a.faultCount Is Null, 0, a.faultCount).
See the excellent explanation here: http://allenbrowne.com/QueryPerfIssue.html
Also, if your tables are in SQL Server or Oracle, using Nz() will force more of the query to be executed locally, with a HUGE performance impact.
Microsoft Access' version of IsNull is different than most SQL versions; it simply returns TRUE if the value is NULL, and FALSE if it isn't.
You need to basically build your own using IIF():
IIF(ISNULL(a.faultCount), 0, a.faultCount)
I think that you are looking for the nz function
Nz(a.faultCount, 0)
will return 0 if the value is null