While am fetching records from the database am getting the ORA-01489: result of string concatenation is too long.
Am having more rows in the table to.
Please find my query below.
SELECT MAX(LTRIM(sys_connect_by_path(TO_CHAR(rn)
||'.'
||MESSAGE,'~'),'~')) MESSAGE
FROM
(SELECT tif,
MESSAGE,
ROWNUM rn
FROM BULL_MESS msg,
BULL_MAPPING MAP
WHERE map.tif = ?
AND msg.message_id = MAP.message_id
AND msg.enabled_flag = 'Y'
)
START WITH rn = 1
CONNECT BY PRIOR rn = rn-1
MINUS
SELECT NULL FROM dual
The sys_connect_by_path function returns a varchar2. varchar2s have a length limit of 4000 bytes in SQL. You must be exceeding that length.
Also, are you sure max is what you want in your query?
Related
Due to a few limitations (which I won't go into here).. our architecture is using queries in Access running via ODBC SQL Server driver.
The following query produces 2 errors:
SELECT Tbl2.columnid,
Tbl2.label,
Tbl2.group1,
Tbl2.group2,
Count(Tbl2.columnid) AS Total
FROM (SELECT scanned AS Group1,
false AS Group2,
scanned AS Label,
scanned AS ColumnID
FROM (SELECT *,
( quantity - productqty ) AS Variance
FROM order_line
WHERE processed = false) AS Tbl1
WHERE wsid = 1 ) AS Tbl2
WHERE Tbl2.columnid = false
GROUP BY Tbl2.group1,
Tbl2.group2,
Tbl2.columnid,
Tbl2.label
ORDER BY Tbl2.group1 DESC,
Tbl2.group2
Error 1: Each GROUP BY Expression must contain at least one column that is an outer reference: (#164)
Error 2: The ORDER BY position number 0 is out of range of the number of items in the Select list (#108)
Its important to note that "scanned" is a BIT field in SQL Server (and therefore Group1, Label, ColumnId are also bits). I believe this is the reason why GROUP BY and ORDER BY are treating it as a constant (value=0), resulting in these errors.
But I do not know how to resolve these issues. Any suggestions would be great!
PS - The reason why 2 sub queries are being used is due to other constraints, where we are trying to get ID, Label, Counts for a column in Kanban.
Based on DRapp's comment and suggestion.. the following works:
SELECT Tbl2.columnid,
Tbl2.label,
Tbl2.group1,
Tbl2.group2,
Count(Tbl2.columnid) AS Total
FROM (SELECT IIf(scanned=True, 'Y', 'N') AS Group1,
'N' AS Group2,
IIf(scanned=True, 'Y', 'N') AS Label,
IIf(scanned=True, 'Y', 'N') AS ColumnID
FROM (SELECT *,
( quantity - productqty ) AS Variance
FROM order_line
WHERE processed = false) AS Tbl1
WHERE wsid = 1 ) AS Tbl2
WHERE Tbl2.columnid = 'N'
GROUP BY Tbl2.group1,
Tbl2.group2,
Tbl2.columnid,
Tbl2.label
ORDER BY Tbl2.group1 DESC,
Tbl2.group2
Not ideal (as the first subquery is generated dynamically, and now needs extra handling if group field is bit. But works! Still open to any other solutions.
I am currently working on a table with approx. 7.5mio rows and 16 columns. One of the rows is an internal identifier (let's call it ID) we use at my university. Another column contains a string.
So, ID is NOT the unique index for a row, so it is possible that one identifier appears more than once in the table - the only difference between the two rows being the string.
I need to find all rows with ID and just keep the one with the longest string and deleting every other row from the original table. Unfortunately I am more of a SQL Novice, and I am really stuck at this point. So if anyone could help, this would be really nice.
Take a look at this sample:
SELECT * INTO #sample FROM (VALUES
(1, 'A'),
(1,'Long A'),
(2,'B'),
(2,'Long B'),
(2,'BB')
) T(ID,Txt)
DELETE S FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY LEN(Txt) DESC) RN
FROM #sample) S
WHERE RN!=1
SELECT * FROM #sample
Results:
ID Txt
-- ------
1 Long A
2 Long B
It might be possible just in SQL, but the way I know how to do it would be a two-pass approach using application code - I assume you have an application you are writing.
The first pass would be something like:
SELECT theid, count(*) AS num, MAX(LEN(thestring)) AS keepme FROM thetable WHERE num > 1 GROUP BY theid
Then you'd loop through the results in whatever language you're using and delete anything with that ID except the one matching the string returned. The language I know is PHP, so I'll use it for my example, but the method would be the same in any language (for brevity, I'm skipping error checking, prepared statements, and such, and not testing - please use carefully):
$sql = 'SELECT theid, count(*) AS num, MAX(LEN(thestring)) AS keepme FROM thetable WHERE num > 1 GROUP BY theid';
$result = sqlsrv_query($resource, $sql);
while ($row = sqlsrv_fetch_object($result)) {
$sql = 'DELETE FROM thetable WHERE theid = '.$row->theid.' AND NOT thestring = '.$row->keepme;
$result = sqlsrv_query($resource, $sql);
}
You didn't say what you would want to do if two strings are the same length, so this solution does not deal with that at all - I'm assuming that each ID will only have one longest string.
I've an Access 2000 .mdb file. I have this query in the same database but on SQL Server. The query works fine in SQL Server, but in Access I get an error; I supposed it is due to ROW_NUMBER().
I can't use vba to make this query because I have to run it with Odbc driver.
SELECT *
FROM
(SELECT
*,
ROW_NUMBER() OVER (ORDER BY cognome,nome ASC) AS RowID
FROM
(SELECT DISTINCT
(a.ID_PAZIENTE) AS codice,
a.NOME AS nome,
a.COGNOME AS cognome,
a.TITOLO AS titolo,
a.TELEFONOABITAZIONE AS tel,
a.TELEFONOUFFICIO AS uff,
a.FAX AS cell,
a.E_MAIL AS email,
a.SESSO AS sesso
FROM
PAZIENTI AS a
WHERE 1 = 1) AS AnagraficheDistinct
) AS Anagrafiche
WHERE
RowID >= 1 AND RowID <= 25
ORDER BY
cognome, nome ASC;
And this is the error:
Syntax error (missing operator) in expression of query: "ROW_NUMBER()
OVER (ORDER BY cognome,nome ASC)
I tried to convert the query following online documentation and this is what I made:
SELECT *
FROM (
SELECT Top 10
*
FROM
(
SELECT DISTINCT TOP 20 p.ID_PAZIENTE,p.cognome,p.nome
FROM PAZIENTI p
ORDER BY p.cognome ASC,p.nome ASC
) AS sub1
ORDER BY sub1.cognome DESC,sub1.nome DESC
) AS anagrafiche
ORDER BY p.cognome ASC,p.nome ASC
Unfortunately this query returns strange results. Changing the start index (How do I implement pagination in SQL for MS Access?), sometimes return 10 results (the page size), sometimes 12 based on the start index (startpos + page size).
I'm doing something wrong or this thing in no possible with Access without VBA?
Thanks
Consider the following. RowNumber() is not available in Access SQL but can possibly be replicated with a rank by name using subquery:
SELECT *
FROM
(SELECT DISTINCT
a.ID_PAZIENTE AS codice,
a.NOME AS nome,
a.COGNOME AS cognome,
a.TITOLO AS titolo,
a.TELEFONOABITAZIONE AS tel,
a.TELEFONOUFFICIO AS uff,
a.FAX AS cell,
a.E_MAIL AS email,
a.SESSO AS sesso,
(SELECT count(*)
FROM PAZIENTI As b
WHERE b.cognome <= a.cognome
AND b.nome <= a.nome) As RowID
FROM PAZIENTI AS a) AS AnagraficheDistinct
) AS Anagrafiche
WHERE RowID >= 1 AND RowID <= 25
ORDER BY cognome, nome;
First of all, the Query in MS-Access is logically completely different from the SQL-Server-Query.
The first one gives you the first 25 rows ordered by cognome,nome.
The Access-Query gives you the last 10 Rows from the first 20 Rows in the specified order.
In Access there is no built-in-Function such as ROW_NUMBER. And because you are using two fields as ordering criteria for the ROW_NUMBER (cognome, nome) the usage of a Count(*) Subquery doesn't work.
But I have instead built a type of RANK-Function in Access and maybe that work's for you. But, it may give also more rows back as you specify for one pagesize, if the number of rows with the same value in cognome is greater than the pagesize. In this query it is important, that only cognome is part of the Count(*) subquery.
SELECT p.*
FROM
(
SELECT codice, cognome, nome, titolo, tel, uff, cell, email
FROM
(
SELECT DISTINCT a.ID_PAZIENTE AS codice, a.COGNOME AS cognome,
a.NOME AS nome, a.TITOLO AS titolo,
a.TELEFONOABITAZIONE AS tel, a.TELEFONOUFFICIO AS uff,
a.FAX AS cell, a.E_MAIL AS email, a.SESSO AS sesso,
(SELECT Count(*) FROM PAZIENTI AS temp
WHERE temp.cognome < a.cognome
) + 1 AS Rank
FROM PAZIENTI AS a
) AS psub
WHERE Rank >= 1 AND Rank <= 5
ORDER BY Rank
) p
ORDER BY cognome, nome
If that doesn't help you, I think, you will need a VBA-Function. But here it is critical to reset the counter before every query.
An other Option is using a Pass-Through-Query and send the first query directly to SQL-Server. You have to specify the odbc-Connectionstring in the Query-Object in Access.
From a table do I want to select the first 4 rows after the first one. I had this in MySQL working as the following:
SELECT * FROM `yp_playlist` LIMIT 1, 4;
I have done some research to see the SQL Server version of this query and came out on the following but this keeps resulting me into an error which keeps me clueless for now.
SELECT id, entry
FROM (
SELECT id, entry, ROW_NUMBER() OVER (ORDER BY id) AS RowNum
FROM playlist
) AS MyDerivedTable
WHERE MyDerivedTable.RowNum BETWEEN 0 AND 10
This is the error:
There was an error parsing the query. [ Token line number = 3, Token line offset = 36, Token in error = OVER ]
With SQL Server Compact 4.0 you can use;
SELECT * FROM [Orders] ORDER BY [Order Date] OFFSET 1 ROWS
FETCH NEXT 4 ROWS ONLY;
SELECT TOP 10 *
FROM ( SELECT id, entry
FROM playlist
ORDER BY id )
one way is to set rowcount
e.g
set rowcount 4
then order your data so you get the ones you want at the top
I've got a .Net web system with a VB.Net front end talking to a SQL Server 2005 back end over ADO.Net. Essentially, what I want to do is this:
Dim command As SqlCommand = New SqlCommand("", connection)
command.CommandText = "SELECT * FROM someTable ORDER BY orderValue #SortOrder"
Dim sortParam As SqlParameter = New SqlParameter("#SortOrder", SqlDbType.varChar, 3)
sortParam.Value = "ASC"
command.Parameters.Add(sortParam)
command.Prepare()
reader = command.ExecuteReader()
Where the sort order would be passed in via a query string or some such. This code throws "Incorrect syntax near '#SortOrder'. Statement(s) could not be prepared."
Is this even possible, or do I have some really dumb syntax error I'm not seeing?
(And, yes, the client is only running .net 2.0, so LINQ-based solutions won't work, sadly.
Thanks, all!
Update / Response:
Well, that's what I thought. Thanks for the sanity check, everybody. (For some context, the command string is currently being built dynamically, but we're moving the system in a more prepared statement direction, and this was one of the edge cases I didn't know was possible.
Thanks again!
No, that won't work.
There are two possibilities that I can think of right off the top of my head to do what you're trying to do:
Build the SQL string dynamically
Return a Data Table from your query, and then use a View to do your sorting.
With another 6 years or so of experience (plus SQL Server Versions), I have a way of accomplishing this.
DECLARE #SortByIdASC AS INT;
SET #SortByIdASC = 1;
WITH cte AS (
SELECT Id, Foo, Bar
, ROW_NUMBER() OVER (ORDER BY Id ASC) AS IdSortAsc
, ROW_NUMBER() OVER (ORDER BY Id DESC) AS IdSortDesc
FROM MyTable
)
SELECT Id, Foo, Bar
FROM cte
ORDER BY CASE WHEN #SortByIdASC = 1 THEN IdSortAsc
WHEN #SortByIdASC = 2 THEN IdSortDesc
ELSE ''
END
, Foo, Bar
This also allows for Sorting up,down, or even excluding that particular column from the given sort order.
While it is possible to update the columns used in a sort. Take the following example:
declare #fname int,#lname int
select #fname=1,#lname=0
select * from [user]
order by case when #Fname=1 then firstname when #lname=1 then lastname end
I don't think you can use this technique to modify the sort order but you can at least change the columns your sorting on. At least when I try get complaints about syntax with SQL 2005
You can in a similar manner to an existing post.
declare #firstSortField int, #secondSortField int
set #firstSortField = 1
set #secondSortField = 3
select firstName, lastName, phoneNumber
from customers
order by
case #firstSortField when 1 then firstName when 2 then lastName when 3 then phoneNumber else null end,
case #secondSortField when 1 then firstName when 2 then lastName when 3 then phoneNumber else null end
I don't think that is possible, only parameter values can be prepared.
Nope, you'd need to build it into the SQL query each time, or if you have a sub set of sort orders, cache the command object for these and re-use as suites.
The short ansswer to the question though is "No"
This does exactly what you asked, and never puts user-entered strings anywhere near the database.
//get the requested order from the query string
string sortOrderRequest = request["SortOrder"].ToUpper();
string sortParam = "";
if ( sortOrderRequest.Equals("ASC"))
sortParam = " order by ordervalue ASC ";
else if (sortOrderRequest.Equals("DESC"))
sortParam = " order by ordervalue DESC ";
Dim command As SqlCommand = New SqlCommand("", connection)
command.CommandText = "SELECT * FROM someTable " + sortParam;
command.Prepare()
reader = command.ExecuteReader()
Sure can do. Create two aliased columns, SortASC and SortDESC, fill these with whatever you want, and sort on them.
-- Testcase setup
DECLARE #OrderASC bit
SET #OrderASC = 0
-- Statement required
SELECT
Users.*,
CASE #OrderASC WHEN 1 THEN Users.Alias ELSE null END AS _SortASC,
CASE #OrderASC WHEN 0 THEN Users.Alias ELSE null END AS _SortDESC
FROM Users
ORDER BY _SortASC, _SortDESC DESC
I extended the accepted answer to reach an effective solution for parameterizing order clause in a SQL query. Here is a sample code :
DECLARE #Sorting VARCHAR(200) = 'CreationTime ASC'
SELECT v.*,
CASE WHEN #Sorting = 'CreationTime ASC' THEN ROW_NUMBER() OVER (ORDER BY v.CreationTime ASC)
WHEN #Sorting = 'CreationTime DESC' THEN ROW_NUMBER() OVER (ORDER BY v.CreationTime DESC)
ELSE ROW_NUMBER() OVER (ORDER BY v.Id ASC) END AS rownum
FROM Vehicles v ORDER BY rownum