i'm trying to write an Oracle query that sorts the results in the same way as MS SQL Server does. I'm toying with the 'NLSSORT' function and it's parameters but i can't get exactly the same results as what i can see with MS SQL Server.
The context is a generic data collection system that supports both Oracle and MS SQL Server. This is a pretty old system that is still under maintenance and development. No entity framework or any recent approaches to handle database interactions.
With a simple order by on MS SQL Server i get this result:
_TEST
04-00031-IPE
04-00044-OG
0A-A
A0-A
SAZ2217
The same query on Oracle returns this:
04-00031-IPE
04-00044-OG
0A-A
A0-A
SAZ2217
_TEST
I have tried many combinations of NLSSORT parameters without any success.
[edit]
By using the 'PUNCTUATION' NLS_SORT parameter value, i get results very close to the MS SQL sorting but there is still differences with substrings that contains sequences of numeric chars. Here is a sample query result:
Oracle
0031-CASTOR-BLOC1-AV-AP
0031-CASTOR-BLOC1-AV-SP
0031-CASTOR-BLOC1-SV-AP
0031-CASTOR-BLOC1-SV-SP
0031-CASTOR-BLOC10-DV-AP
0031-CASTOR-BLOC10-DV-SP
0031-CASTOR-BLOC2-DV-AP
Ms SQL
0031-CASTOR-BLOC10-DV-AP
0031-CASTOR-BLOC10-DV-SP
0031-CASTOR-BLOC1-AV-AP
0031-CASTOR-BLOC1-AV-SP
0031-CASTOR-BLOC1-SV-AP
0031-CASTOR-BLOC1-SV-SP
0031-CASTOR-BLOC2-DV-AP
Thank you for your help!
I finally found this solution:
ORDER BY NLSSORT(COLUMN_NAME, 'NLS_SORT = FRENCH_M')
At least in my particular context, i get the same sorting under both MS SQL Server (default sorting) and Oracle.
Here is two useful links:
http://www.myoracleguide.com/xl/Linguistic_Sorting_Frequently_Asked_Questions.htm
http://download.oracle.com/docs/cd/B19306_01/server.102/b14225/ch5lingsort.htm#NLSPG005
Could consider use of rpad function?
e.g.
select name, rpad(upper(replace(translate(name,'_','+'),'-','') ),15,'0') as v1
from sorttest order by
rpad(upper(replace(translate(name,'_','+'),'-','') ),15,'0')
Related
I need to get a count of a DB table.
When I do the below I can see that the table enumerates (so looks like the rows come back then get counted on the app server side) but I'd like the SQL server to do the counting then return just the count.
db.Places.Where(x => x.City == 'San Jose').Count()
This totally depends on the Linq to SQL provider that you're using, but most of them should translate your LINQ statement into an actual server side count.
You will need to enable logging on your provider or turn on profiling on your database in order to see what actual SQL was sent to it.
PS: Please tag with the appropriate provider and SQL server (for example: linq-to-sql sql-server)
We use Entity Frameworks for DB access and when we "think" LIKE statement - it actually generates CHARINDEX stuff. So, here is 2 simple queries, after I simplified them to prove a point on our certain server:
-- Runs about 2 seconds
SELECT * FROM LOCAddress WHERE Address1 LIKE '%1124%'
-- Runs about 16 seconds
SELECT * FROM LOCAddress WHERE ( CAST(CHARINDEX(LOWER(N'1124'), LOWER([Address1])) AS int)) = 1
Table contains about 100k records right now. Address1 is VarChar(100) field, nothing special.
Here is snip of 2 plans side by side. Doesn't make any sense, shows 50% and 50% but execution times like 1:8
I searched online and general advice is to use CHARINDEX instead of LIKE. In our experience it's opposite. My question is what causing this and how we can fix it without code change?
I will answer my own question since it was hard to find correct answer and I was pointed to the problem by SQL Server 2012 Execution Plan output. As you see in original question - everything looks OK on surface. This is SQL Server 2008.
When I run same query on 2012 I got warning on CHARINDEX query. Problem is - SQL Server had to do type conversion. Address1 is VarChar and query has N'1124' which is Unicode or NVarChar. If I change this query as so:
SELECT *
FROM LOCAddress
WHERE (CAST(CHARINDEX(LOWER('1124'), LOWER([Address1])) AS int))
It then runs same as LIKE query. So, type conversion that was caused by Entity Framework generator was causing this horrible hit in performance.
First, as you can see both queries are identical and neither can use index. CHARINDEX and LIKE perform same with wildcard. Ex: %YourValue%. However, there performance varies when you use wildcard like 'YourValue%'. Here, LIKE operator will likely to perform faster than CHARINDEX because it may allow partial scan of the index.
Now, in your case, both queries are same but there performance is difference because of following possible reason:
Statistics: SQL Server maintains statistics for sub string in string columns which are use by LIKE operator but not fully usable for CHARINDEX. In that case, LIKE operator will work faster than CHARINDEX.
You can force SQL Server to use index for CHARINDEX with proper table hints
Ex: FROM LOCAddress WITH (INDEX (index_name))
Read more Here, which in section "string summary stastics" says:
SQL Server 2008 includes patented technology for estimating the selectivity of LIKE conditions. It builds a statistical summary of
substring frequency distribution for character columns (a string
summary). This includes columns of type text, ntext, char, varchar,
and nvarchar. Using the string summary, SQL Server can accurately
estimate the selectivity of LIKE conditions where the pattern may have
any number of wildcards in any combination.
I'm new in SSRS and I want to know if it's possible to display a result of a complex query (which run perfectly on SSMS) in my report?
The problem is that I have an Over statement in my Query:
LEAD(Flow.MeasurementDate) OVER (Partition by
ComponentId, NominationCycle, LocationType, Frequency, FlowTypeId, UnitofMeasurement
ORDER BY MeasurementDate) nextMeasurement,
MAX(Flow.MeasurementDate) OVER (PARTITION BY
ComponentId, NominationCycle, LocationType, Frequency, FlowTypeId, UnitofMeasurement
) maxMeasurement
The error message is:
The OVER SQL construct or statement is not supported.
If it's possible please give me few steps to achieve this.
The Over construct is not supported by the SSRS query designer but the report should still work when the SQL is sent to Sql Server for processing.
If it doesn't, check that your database isn't running in a compatibility level where the Over construct is unsupported (80 or earlier).
If all else fails, an alternative is to put your query in a stored procedure and call that from SSRS.
That's just what SSRS is used for in general.
The steps are the same, no matter if it's a simple or complex query.
You use your query to fill a dataset and display this in a table on your report.
What you need is just a basic SSRS tutorial as it can be found here:
http://msdn.microsoft.com/en-us/library/ms167305.aspx
I am trying to create a Pass-through SQL statement from my MS Access 2003 (Yeah, I know it's oldschool but my hands are tied :/) to an Oracle DB on a Server.
Long story short, the server-table contains freezer models, where each model exists 1 to 5 times with the ID prefixed with a value indicating it's condition. The problem is, that I have to fetch all "versions" of a freezer. In Access I would write something like:
SQL = "SELECT Right(FREEZERS.ID,4) FROM FREEZERS WHERE Right(FREEZERS.ID,4) = '" & myID & "'"
But this triggers an error in my Pass-through query to Oracle. Is it even possible to write expressions like this in a pass-through query?
I am using vba and a QueryDef with a connectstring to the server (which works fine if i strip the Right()-expression), and then open a recordset with the result.
Thanks on beforehand, Viggo
EDIT:
Ah, sorry..
Took one last Googling and the Answer popped up:
Apparently Oracle has a different syntax for some of these functions. In this case I found that Oracle has a SUBSTR-function and a LENGTH-function, fixing my problem..
To others in search: The key is searching for Oracle syntax rather than Pass-through syntax..
Source:
http://peoplesofttipster.com/2008/08/18/substringing-and-oracle-sql-basic-trick/
Hope it can help someone else :)
As described in the above:
In Pass-Through queries the SQL language of the server.. :)
Let's say I have a table that has a column of XML type data. Within SQL, I can execute the following statement:
select top 10 *,
Content.value('(/root/item/value)[1]', 'float') as Value
from xmltabletest
where Content.value('(/root/item/MessageType)[1]', 'int') = 1
The result set contains only the records matching the criteria, and it extracts a value from the XML into a column called 'Value'. Nice and simple.
Can the same thing be achieved with Linq To SQL?
I'd like to get SQL to do the heavy lifting and only return data matching my criteria rather than having to select, transfer, and then process a potentially massive chunk of data. As far as I can tell this isn't possible at the moment, but I thought I should ask.
(The environment is .NET 3.5, VS2008, SQL Server 2005 if that helps)
I'm not exactly sure if this is out of date now, but according to Scott Guthrie XML datatypes are:
represented as strings in LINQ to SQL
Entities. You could use XLINQ to query
on an XML column within your LINQ to
SQL entitiy - but this querying would
happen in your middle-tier (within
ASP.NET). You can't execute a remote
XQuery against the database and filter
returned results based on that in the
first release.
So in answer to your question, I'd say "no."