Cannot use modulus only in query window that connected to server - sql-server

Currently I have a problem with SQL Server.
I just do a query like this :
declare #var2 int
set #var2 = ((7500.50 * 100) % 100)
select #var2
If I execute in local machine (query window connected to local), it returns 50.
But if I run that query in query window that is connected to my office server, it results in:
Msg 8117, Level 16, State 1, Line 2
Operand data type numeric is invalid for modulo operator.
Msg 206, Level 16, State 2, Line 2
Operand type clash: int is incompatible with void type
I've tried in both SQL Server 2005 and 2008.
Anyone ever face same problem or know the solution ?
Thanx a lot all.

Check the compatibility level of the server. It is likely at 80, which is for SQL Server 2000 compatibility. In SQL Server 2000, modulo only supported the INT data types. In SQL 2005 and up, other numeric data types are allowed and implicit conversions will happen, since in your formula you have both numeric and integer data types.
I found a script to modify compatibility level on all databases of a server with filtering of databases you wouldn't want to change.

Related

T-SQL BULK INSERT type mismatch

I am trying to do a simple BULK INSERT from a large CSV file to a table. The table and the file have matching columns. This is my code:
BULK INSERT myTable
FROM 'G:\Tests\mySource.csv'
WITH (
FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
-- ROWTERMINATOR = '0x0a',
BATCHSIZE = 1000,
MAXERRORS = 2
)
GO
As you can see I have tried with row terminators \n and 0x0a (and a bunch more)
I keep getting a type mismatch error:
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 2, column 18 (createdAt).
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 3, column 18 (createdAt).
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 4, column 18 (createdAt).
Msg 4865, Level 16, State 1, Line 1
Cannot bulk load because the maximum number of errors (2) was exceeded.
Msg 7399, Level 16, State 1, Line 1
The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.
Msg 7330, Level 16, State 2, Line 1
Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".
Column createdAt is of type datetime:
CREATE TABLE [dbo].[myTable]
(
...
[createdAt] [datetime] NULL,
...
)
These are the values of the createdAt column as taken from the first three rows:
2020-08-22 13:51:57
2020-08-22 14:13:13
2020-08-22 14:16:23
I also tried with a different number format as suggested. I also tried changing the column type to DATETIME2(n):
2020-08-22T13:51:57
2020-08-22T14:13:13
2020-08-22T14:16:23
I have no idea what else to review.
I would appreciate any help.
Thanks!
There are many formats of string literals to be converted to dates & times supported by SQL Server - see the MSDN Books Online on CAST and CONVERT. Most of those formats are dependent on what settings you have - therefore, these settings might work some times - and sometimes not. And the DATETIME datatype in particular is notoriously picky about what formats of string literals work - and which others (most) don't.... DATETIME2(n) is much more forgiving and less picky to deal with!
The way to solve this is to use the (slightly adapted) ISO-8601 date format that is supported by SQL Server - this format works always - regardless of your SQL Server language and dateformat settings.
The ISO-8601 format is supported by SQL Server comes in two flavors:
YYYYMMDD for just dates (no time portion); note here: no dashes!, that's very important! YYYY-MM-DD is NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:MM:SS for dates and times - note here: this format has dashes (but they can be omitted), and a fixed T as delimiter between the date and time portion of your DATETIME.
This is valid for SQL Server 2000 and newer.
If you use SQL Server 2008 or newer and the DATE datatype (only DATE - not DATETIME!), then you can indeed also use the YYYY-MM-DD format and that will work, too, with any settings in your SQL Server.
Don't ask me why this whole topic is so tricky and somewhat confusing - that's just the way it is. But with the YYYYMMDD format, you should be fine for any version of SQL Server and for any language and dateformat setting in your SQL Server.
The recommendation for SQL Server 2008 and newer is to use DATE if you only need the date portion, and DATETIME2(n) when you need both date and time. You should try to start phasing out the DATETIME datatype if ever possible
In your case, I'd try one of two things:
if you can - use DATETIME2(n) instead of DATETIME as your column's datatype - that alone might solve all your problems
if you can't use DATETIME2(n) - try to use 2020-08-22T13:51:57 instead of
2020-08-22 13:51:57 for specifying your date&time in the CSV import file.

SQL Server - Select YEAR error

Currently using SQL Server 2008. In an effort to debug some bad date data being processed, the following code was written with an example of the bad data.
SELECT ISDATE('10-22-002')
SELECT YEAR('10-22-002')
Running the statements on database A, the results are: '1' and '2002'.
Running the statements on database B, the results are: '1' and an error.
The date format is MDY on all sessions before running the statements.
Msg 241, Level 16, State 1
Conversion failed when converting datetime from character string.
Everything I'm able to find says the date format is set at either server or session level. Is there a setting at the DB level for this?
You need to cast '10-22-002' as a datetime.
SELECT YEAR(cast('10-22-002' as datetime))

SQL-Server Error Could not find method 'STContains'

I'm using the mssql server to implement a spatial database. I have one table (Ways) containing a geography column called geoline, that is of LINESTRING type.
I want to select the geoline containing a specific POINT, with the coordinates (38.731611,-9.135336).
I tried this:
SELECT geoLine.STAsText()
FROM Ways
WHERE geoLine.STContains(geometry::STGeomFromText('POINT(38.731611 -9.135336)', 0));
But it returned the following error:
Msg 4145, Level 15, State 1, Line 2 An expression of non-boolean type
specified in a context where a condition is expected, near ';'.
What can I do? Any idea for a success query?
Thanks
I think you are using SQL SERVER 2008 or below thats why you are getting that error because
STContains (geography Data Type) will work from SQL SERVER 2012 and above (source).
In your case to find instance completely contains another geometry instance you need a geometry data type.
FIDDLE DEMO HERE
CREATE TABLE #Ways
(geoLine GEOMETRY)
INSERT INTO #Ways
(geoLine)
VALUES (geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0)),
(geometry::STGeomFromText('POINT(38.731611 -9.135336)', 0))
SELECT geoLine.STAsText() AS geoLine,geoLine
FROM #Ways
SELECT geoLine.STAsText() AS geoLine
FROM #Ways
WHERE geoLine.STContains(geometry::STGeomFromText('POINT(38.731611 -9.135336)', 0)) = 1
According to T-SQL documentation, STContains returns a BIT data type, so your WHERE condition should look like this I think :
SELECT geoLine.STAsText()
FROM Ways
WHERE geoLine.STContains(geometry::STGeomFromText('POINT(38.731611 -9.135336)', 0)) = 1;

How to concatenate a string, an integer and a sequence in SQL Server 2014

I have requirement where I need to concatenate a fixed string, a integer variable and a sequence. I am not sure how do I go about doing it in SQL Server 2012. I have been able to implement the same in PostgreSQL, but can anyone assist me in doing the same in SQL Server.
I have tried this code:
FORMAT((NEXT VALUE FOR dtr_seq),('DTR'++#lc_org_unit_id));
But it gives and error saying:
Msg 8116, Level 16, State 1, Procedure sp_dtr, Line 27
Argument data type int is invalid for argument 2 of format function.
The code I used in PostgreSQL is like this:
SELECT ('DTR'||lc_org_unit_id||nextval('ccdb.dtr_seq');
The result that I am expecting is something like this:
DTR46361002
Please suggest me how do I go about implementing the same in SQL Server 2012
SELECT 'DTR' + CAST((NEXT VALUE FOR dtr_seq) AS VARCHAR(20))
+ CAST(#lc_org_unit_id AS VARCHAR(20))
Here is the function in 2012. SELECT CONCAT('DTR',lc_org_unit_id,nextval('ccdb.dtr_seq')). MSSQL 2012 will handle the conversions from char to int most of the time.

T-SQL data type REAL FLOAT(n) on SQL Server

Is anyone aware of the reasons why the following line of T-SQL code works (under SQL Server 2008)?
SELECT cast(2 as real(10))
I expect the server to complain in the very same way it does when I attempt this:
declare #x real(10)
set #x = 4.1234567
select #x
and I get:
Msg 2716, Level 16, State 1, Line 16
Column, parameter, or variable #2: Cannot specify a column width on data type real.
I realise that for MS SQL 2008 there is a data type REAL equivalent to FLOAT(24).
I just would like to know why CAST does not complain, i.e., it was possible to write nonsense as REAL(4,2) within CAST (under SQL 2000), it works fine with REAL(10) under SQL 2008 (again in CAST)?
Any suggestions and clarification appreciated. Thank you.
It would appear that CAST (and CONVERT) translates type synonyms (such as real) into their underlying type (i.e. float), for which length specifiers are valid. For another example, you can do:
SELECT CONVERT(sysname(10),'abcdefghijkl')
But you cannot declare a variable of type sysname(10), since sysname is a synonym for nvarchar(128) (or varchar(30), depending on SQL version)
In short, I'd say it's a quirk of how CAST/CONVERT work, but shouldn't be relied upon.

Resources