The application I am using is written by dinosaurs, using *= and =* operators in sql queries. These queries do joins on 10 or so tables, and I have about 500 such queries. And all I have time for is to upgrade the existing software as-is instead of writing any code. So, updating the query builder functions in all of them is not feasible.
Sadly, I am supposed to upgrade the application to use SQL server 2014, instead of 2005. And in 2014, the backward compatibility for a lot of operators is removed. So, I need to enable some kind of compatibility option in SQL server 2014, if it is available. But, I don't know if there is such a thing, and if it is, how to enable it.
Found a query to find the current compatibility setting. Posting it here, in case someone else needs it.
WITH compatversions AS (
SELECT 65 AS MajorVersion ,'SQL Server 6.5' AS ServerVersion
UNION
SELECT 70,'SQL Server 7.0'
UNION
SELECT 80 , 'SQL Server 2000'
UNION
SELECT 90 , 'SQL Server 2005'
UNION
SELECT 100 , 'SQL Server 2008/R2'
UNION
SELECT 110 , 'SQL Server 2012'
UNION
SELECT 120 , 'SQL Server 2014'
)
SELECT TOP 3 ServerVersion,MajorVersion
,ServerVersion + ' ('+ CONVERT(VARCHAR(3),MajorVersion) +')' AS DropDownFormat
FROM compatversions
WHERE MajorVersion IN (
SELECT TOP 3 MajorVersion
FROM compatversions
WHERE MajorVersion <= CONVERT(INT,CAST(##microsoftversion/ 0x1000000 AS VARCHAR(3)) + '0')
ORDER BY MajorVersion DESC)
ORDER BY MajorVersion ASC;
Apparently, SQL server 2014 supports up to 2008 compatibility.
Related
I'm trying to select a null value on a IP21 Database like we do in Oracle databases or Sql Server, e.g:
Oracle: SELECT NULL FROM DUAL
Sql Server: SELECT NULL
Anyone know how i can do this?
Strange situation... New physical severs, new install of SQL Server 2019 Enterprise version :
Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64) Sep 24 2019 13:48:23 Copyright (C) 2019 Microsoft Corporation Enterprise Edition: Core-based Licensing (64-bit) on Windows Server 2019 Standard 10.0 (Build 17763: ).
Testing the performance by creating the first database like this :
CREATE DATABASE DB_BENCH
GO
DECLARE #SQL NVARCHAR(max) = N'';
SELECT #SQL = #SQL + N'ALTER DATABASE DB_BENCH MODIFY FILE (NAME = ''' + name + N''', SIZE = 10 GB, FILEGROWTH = 64 MB);'
FROM DB_BENCH.sys.database_files;
SET #SQL = #SQL + N'ALTER DATABASE DB_BENCH SET RECOVERY SIMPLE;'
EXEC (#SQL);
GO
And the objects in the database like this :
USE DB_BENCH
GO
SET NOCOUNT ON;
GO
CREATE TABLE T_TIME_INTERVAL_TIV
(TIV_ID INT NOT NULL IDENTITY PRIMARY KEY,
TIV_GROUP INT,
TIV_DEBUT DATETIME2(0),
TIV_FIN DATETIME2(0))
GO
TRUNCATE TABLE T_TIME_INTERVAL_TIV;
GO
BULK INSERT T_TIME_INTERVAL_TIV
FROM "C:\DATA_SQL\intervals.txt"
WITH (KEEPIDENTITY ,
FIELDTERMINATOR = '\t',
ROWTERMINATOR = '\n');
GO
CREATE VIEW V
AS
SELECT TIV_GROUP AS id, TIV_DEBUT AS intime, TIV_FIN AS outtime
FROM T_TIME_INTERVAL_TIV
GO
The intervals.txt datafile contains 1 million lines.
You can have it at :
https://1drv.ms/t/s!AqvZfiQYoNpBiCD65D4zaRbch5s-?e=UicEYu
The query that produce the bug :
WITH T1 As
(SELECT id, intime
FROM #T
UNION ALL
SELECT id, outtime FROM #T),
T2 As
(SELECT ROW_NUMBER() OVER(PARTITION BY id ORDER BY intime) NN, id, intime
FROM T1 T1_1),
T3 As
(SELECT T2_1.NN - ROW_NUMBER() OVER(PARTITION BY T2_1.id ORDER BY T2_1.intime,T2_2.intime) NN1,
T2_1.id, T2_1.intime intime, T2_2.intime outtime
FROM T2 T2_1
INNER JOIN T2 T2_2
ON T2_1.id=T2_2.id
And T2_1.NN=T2_2.NN-1
WHERE EXISTS (SELECT *
FROM V S
WHERE S.id=T2_1.id
AND (S.intime < T2_2.intime AND S.outtime>T2_1.intime))
OR T2_1.intime = T2_2.intime)
SELECT id, MIN(intime) intime, MAX(outtime) outtime
FROM T3
GROUP BY id, NN1
ORDER BY id, intime, outtime;
We tested this query on 2 different servers... with the same SQL Server installation.
The result is always :
Msg 601, Level 12, State 1, Line ...
Could not continue scan with NOLOCK due to data movement.
With an installation of :
SQL Server 2019 (RTM) - 15.0.2000.5 (X64) Sep 24 2019 13:48:23 Developer Edition (64-bit) on Windows Server 2019 Standard 10.0 (Build 17763: ) (Hypervisor)
There is no problem...
We tested the databases with DBCC CHECKDB () WITH DATA_PURITY. No errors.
Can you reproduce with your different editions/patches (CU) and give me your results for which are alright or not ?
If some of you have already the bug I will add an entry in SQL Azure feedback...
Thanks
After many investigation, we found that it is really a SQL Server bug.
The bug disappear when we execute a :
UPDATE STATISTICS T_TIME_INTERVAL_TIV WITH FULLSCAN;
Or when whe "hint" the query with OPTION (MAXDOP 1)
Sometime a stack dump appear (not Always) showing this type of messages :
A time-out occurred while waiting for buffer latch -- type 4, bp 0000029BA883BDC0, page 9:407, stat 0x10b, database id: 2, allocation unit Id: 422212465393664/140737488683008, task 0x0000029B86723848 : 14, waittime 300 seconds, flags 0x1a, owning task 0x0000029B86713848. Not continuing to wait.
Which is the tempdb. A Stack Dump is systematically recorded on file.
We will call the MS hotline as soon as possible.
Thanks to all of you.
I have a SQL Server 2017 server running a database in 2012 compatibility mode. However when I try using the new to 2017 T-SQL command string_agg(), it works. I would expect a syntax error because string_agg() isn't valid for 2012 mode.
Here is the SQL I'm using:
SELECT
Compatibility_Level,
CASE Compatibility_Level
WHEN 65 THEN 'SQL Server 6.5'
WHEN 70 THEN 'SQL Server 7.0'
WHEN 80 THEN 'SQL Server 2000'
WHEN 90 THEN 'SQL Server 2005'
WHEN 100 THEN 'SQL Server 2008/R2'
WHEN 110 THEN 'SQL Server 2012'
WHEN 120 THEN 'SQL Server 2014'
WHEN 130 THEN 'SQL Server 2016'
WHEN 140 THEN 'SQL Server 2017 <<<'
ELSE 'new unknown - ' + CONVERT(VARCHAR(10), Compatibility_Level)
END AS VersionName
FROM
sys.databases
WHERE
Name = DB_NAME()
DECLARE #x TABLE (col1 INT, col2 VARCHAR(5))
INSERT INTO #x
VALUES (1, 1), (1, 2), (1, 3), (2, 1), (2, 2)
SELECT * FROM #x
SELECT col1, string_agg(col2,', ')
FROM #x
GROUP BY col1
Here is the output:
Compatibility_Level VersionName
------------------- ------------------------
110 SQL Server 2012
(1 row affected)
(5 rows affected)
col1 col2
----------- -----
1 1
1 2
1 3
2 1
2 2
(5 rows affected)
col1
----------- ------------------------------------
1 1, 2, 3
2 1, 2
(2 rows affected)
The purpose of Compatibility Mode is to ensure that statements which were valid in previous versions of SQL Server behave in the same way in newer versions of SQL server.
This includes statements which were previously valid but have become invalid in the new version, and statements which have a different meaning or behave differently between versions.
Statements which were invalid in previous versions are not included in this goal.
Why? Consider upgrading. You first want to convert everything to the new syntax and functions, then when you are satisfied everything is ready, you can raise the compatibility level. If you can't allow things which are valid in the new compatibility level (but invalid or meaningless before) then it becomes difficult to migrate to the higher level.
Interestingly enough I found no post for this specific, but basic issue.
Goal: update the latest budgetid record docstatus = 0. Then I want to update the next-to-last budgetid record docstatus = 1. I am trying this within PHP but also testing in my SQL Server SEM and it is failing there, too.
My SQL Server statement:
select
budgetid, docstatus, datechanged
from
ccy_budget
where
activityid = 11111
order by
datechanged desc
limit 1,1;
Error that occurs in SEM is:
Incorrect syntax near 'limit'.
Yet in w3schools this [sample] sql works just fine:
SELECT *
FROM Customers
ORDER BY postalcode DESC
LIMIT 1,1;
Seems so simple, surely I am missing something fundamental.
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64)
Apr 2 2010 15:48:46
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: ) (Hypervisor)
Equivalent syntax in SQL Server would be
select *
from table
order by somerow desc
offset 1 rows fetch next 1 rows only;
But the above is available from SQL Server 2012 on, so for your version, you have to some thing like below
;with cte
as
(
select *,row_number() over (order by postalcode desc) as rn
from table
)
select * from cte where rn=2
I need a safe (i.e consistent, robust) way of detecting whether or not the sql server I'm accessing is Sql Express. I think I'd prefer to be able to do this from TSQL, since I already have a connection string and all the libraries I need to execute TSQL (this should help avoid issues with whether or not WMI is installed/running, the user has permissions to access the registry etc).
Does anyone know of a way to do this ?
Thanks.
PS: Basically I want to do this so I can monitor my database size against the 4gb limit and take action when I approach it... but if I'm running on a full Sql Server edition then I don't want the code to worry about it since there is no (practical) hard coded limit. I could put in a manual setting in my program, but it would be much nicer if the code just did the right thing automatically, hence the need to know if the server is the 'Express' edition or not.
Use
SELECT SERVERPROPERTY('EditionID')
or
SELECT SERVERPROPERTY('Edition')
to detect which version of SQLServer is running.
http://msdn.microsoft.com/en-us/library/ms174396.aspx
This will return 0 if it's not, and something non-zero (126 here) if it is:
select charindex('Express Edition',##version)
Example in a boolean context:
if (select charindex('Express Edition',##version)) > 0
begin
print 'Express edition!'
end
else
begin
print 'Not Express edition!'
end
The SERVERPROPERTY function was already mentioned in multiple other answers, but there's a better solution than checking if a string contains "Express Edition": the EngineEdition argument, which returns an int value.
Quote from the link:
EngineEdition
Database Engine edition of the instance of SQL Server installed on the
server.
1 = Personal or Desktop Engine (Not available in SQL Server 2005 and
later versions.)
2 = Standard (This is returned for Standard, Web, and Business
Intelligence.)
3 = Enterprise (This is returned for Evaluation, Developer, and both
Enterprise editions.)
4 = Express (This is returned for Express, Express with Tools and
Express with Advanced Services)
5 = SQL Database
6 - SQL Data Warehouse
Base data type: int
So you can check for Express Edition like this:
if SERVERPROPERTY('EngineEdition') = 4
begin
select 'Express'
end
else
begin
select 'not Express'
end
There are a number of ways:
EXEC sp_server_info 2
Or
SELECT ##version
Or
SELECT serverproperty('ProductVersion')
You Can Also do this:
DECLARE #ver nvarchar(128)
SET #ver = CAST(serverproperty('ProductVersion') AS nvarchar)
SET #ver = SUBSTRING(#ver, 1, CHARINDEX('.', #ver) - 1)
IF ( #ver = '8' )
SELECT 'SQL Server 2000'
ELSE IF ( #ver = '9' )
SELECT 'SQL Server 2005'
ELSE
SELECT 'Unsupported SQL Server Version'
More info at: http://blog.devstone.com/aaron/default,date,2006-12-15.aspx
You can use SERVERPROPERTY('Edition') which will return "Express Edition"
What happens in SQL Server Express if you don't monitor the size, but get to the limit? Are there warnings first? Events in the event log?
If so, then you might do better to allow SQL Server to issue the warnings, and then just listen to them. The same might well apply for a SQL Server Enterprise installation if a disk gets full.