I'm running into an ORA-00933: SQL command not properly ended error. What I am doing is querying on a table I built from a With query. I've been combing through Stack, trying to resolve this issue with every correctly answered question that I could find, but I still run into the error. It's something small and easy to fix I am sure. it's just beyond me at this point. The error occurs on the line with the second select statement:
;WITH sums
AS (SELECT a.client_number_id AS Client_Number_ID,
Count(Decode(a.sub_type_code, 'A', 1)) AS Applications,
Count(Decode(a.sub_type_code, 'S', 1)) AS License,
Count(Decode(a.sub_type_code, 'L', 1)) AS Lease
FROM mta_spatial.mta_acquired_tenure_svw a
WHERE a.tenure_type_description = 'Coal'
GROUP BY a.client_number_id)
SELECT client_number_id,
applications,
license,
lease,
applications + license + lease AS 'GrandTotal'
FROM sums;
applications + license + lease AS 'GrandTotal'
should be
applications + license + lease AS "GrandTotal"
quotes are for string
double quotes for field names.
Enclosing the alias in double quotes would make it case sensitive. In case you wish to make the alias case insensitive, write it without quotes. Oracle treats such cases as upper case by default. Therefore, Grandtotal, GRANDTOTAL,
grandtotal would all return the desired result.
applications + license + lease AS GrandTotal
Thanks everyone for their contribution. I solved it when I removed the semicolon before the 'WITH' statement. I borrowed the query from another stack thread
To calculate sum() two alias named columns - in sql
and modified it to my own use. They had used a semicolon, so I didn't think to remove it. I'm not sure why they had that there to begin with. this is my first attempt at using the 'WITH' clause.
Related
When I run this on Microsoft Access:
SELECT
'BANNER',
USRAUDT_KEY_VALUE_1,
UCRACCT_PREM_CODE,
CONCAT(CONCAT(USRAUDT_KEY_VALUE_1,'_'),UCRACCT_PREM_CODE) AS "ACCOUNT",
USRAUDT_USER_ID,
' ',
' ',
USRAUDT_ACTIVITY_DATE,
' ',
'bill cycle',
' ',
UCRACCT_STATUS_IND,
USRAUDT_NEW_VALUE,
' ',
UCRACCT_BILL_PRES_TYPE
FROM
USRAUDT
INNER JOIN UCRACCT ON (USRAUDT_KEY_VALUE_1) = UCRACCT_CUST_CODE
WHERE 1=1
AND USRAUDT_NEW_VALUE In ('E','R')
and USRAUDT_USER_ID <> 'UEADMIN'
and USRAUDT_COLUMN_NAME='UCBCUST_PAPERLESS_IND'
and (USRAUDT_ACTIVITY_DATE >= '27-JAN-2020')
and (USRAUDT_ACTIVITY_DATE <= '03-FEB-2020')
and ((USRAUDT_TABLE_NAME)='UCBCUST')
AND UCRACCT_STATUS_IND='A'
and UCRACCT_BILL_PRES_TYPE in ('E','L','U','V')
I get the error "Join expression NOT supported", I've tried using AND but still no avail. Help please.. :(
No two SQL dialects are exactly the same including MS Access SQL and others from various DBMS's. Specifically, your attempted query includes several issues:
Join: ON clauses in MS Access requires table or table alias qualifiers with period notations. Generally in SQL, the best practice is to qualify every column reference in SELECT, ON, WHERE, GROUP BY and other clauses whenever you join more than one table. This facilitates code maintainability and readability.
FROM USRAUDT d
INNER JOIN UCRACCT c
ON d.USRAUDT_KEY_VALUE_1 = d.UCRACCT_CUST_CODE
Functions: There is no built-in CONCAT function. Use & instead or build your own via VBA function (accessible through queries only in MS Access GUI and not backend via ODBC/OLEDB): d.USRAUDT_KEY_VALUE_1 & '_' & c.UCRACCT_PREM_CODE
Quotes: Double even single quotes used in column aliases will render such symbols (", ') directly in query column headers. Similarly, if you use quotes for table aliases, you will then need to reference table with such symbols. For example, SELECT "d".* FROM USRAUDT "d" or SELECT 'd'.* FROM USRAUDT 'd' works but fails if you use no quotes: SELECT d.* .... To escape special characters or spaces in MS Access, use square brackets or backticks. Column and table names are case insensitive in Access regardless of symbols.
Aliases: Any columns without column names or aliases will render as Expr#### where number follows 1000 + column integer (zero-index). To avoid this result, provide actual column aliases even for constants like '_' unless SELECT is used in insert-select query which does not matter. Again, generally in SQL, the best practice is to always provide unique column aliases as some other engines will raise exceptions.
Dates: Dates in MS Access cannot be compared to its string representation but need to be casted to dates with CDate or enclosed with # and must adhere to representative forms of dates such as 'MM/DD/YYYY' or 'DD/MM/YYYY'. Usually, the best format though is ISO system date format: 'YYYY-MM-DD':
and (d.USRAUDT_ACTIVITY_DATE >= #2020-01-27#)
and (d.USRAUDT_ACTIVITY_DATE <= CDate('02/03/2020')
I am trying to write a query in Hive with a Case statement in which the condition depends on one of the values in the current row (whether or not it is equal to its predecessor). I want to evaluate it on the fly, this way, therefore requiring a nested query, not by making it another column first and comparing 2 columns. (I was able to do the latter, but that's really second-best). Does anyone know how to make this work?
Thanks.
My query:
SELECT * ,
CASE
WHEN
(SELECT lag(field_with_duplicates,1) over (order by field_with_duplicates) FROM my_table b
WHERE b.id=a.id) = a.field_with_duplicates
THEN “Duplicate”
ELSE “”
END as Duplicate_Indicator
FROM my_table a
Error:
java.sql.SQLException: org.apache.spark.sql.AnalysisException: cannot recognize input near 'SELECT' 'lag' '(' in expression specification; line 4 pos 9
Notes:
The reason I needed the complicated 'lag' function is that the unique Id's in the table are not consecutive, but I don't think that's where it's at: I tested by substituting another simpler inner query and got the same error message.
Speaking of 'duplicates', I did search on this issue before posting, but the only SELECT's inside CASE's I found were in the THEN statement, and if that works the same, it suggests mine should work too.
You do not need the subquery inside CASE:
SELECT a.* ,
CASE
WHEN prev_field_with_duplicates = field_with_duplicates
THEN “Duplicate”
ELSE “”
END as Duplicate_Indicator
FROM (select a.*,
lag(field_with_duplicates,1) over (order by field_with_duplicates) as prev_field_with_duplicates
from my_table a
)a
or even you can use lag() inside CASE instead without subquery at all (I'm not sure if it will work in all Hive versions ):
CASE
WHEN lag(field_with_duplicates,1) over (order by field_with_duplicates) = field_with_duplicates
THEN “Duplicate”
ELSE “”
END as Duplicate_Indicator
Thanks to #MatBailie for the answer in his comment. Don't I feel silly...
Resolved
I have a data source like following
If I ran the following sql query it removes all the records with "Seg Type" MOD and ignores the Fnn range given.
select * from NpsoQueue
where SegmentType not in ('MOD')
and Fnn not between 0888452158 and 0888452158
I want the query to consider both conditions. So, if I ran the query it should remove only the first record
The logic in your where clause is incorrect
Use
select * from NpsoQueue
where NOT (
SegmentType = 'MOD'
and Fnn between '0888452158' and '0888452158'
)
Also, a number with a leading zero is a string literal so you need to put single quotes around it to preserve the leading zero and stop implicit casts happening
As mentioned by #TriV you could also use OR. These are fundamental boolean logic concepts, i.e. not related to SQL Server or databases
I am taking a text input from the user, then converting it into 2 character length strings (2-Grams)
For example
RX480 becomes
"rx","x4","48","80"
Now if I directly query server like below can they somehow make SQL injection?
select *
from myTable
where myVariable in ('rx', 'x4', '48', '80')
SQL injection is not a matter of length of anything.
It happens when someone adds code to your existing query. They do this by sending in the malicious extra code as a form submission (or something). When your SQL code executes, it doesn't realize that there are more than one thing to do. It just executes what it's told.
You could start with a simple query like:
select *
from thisTable
where something=$something
So you could end up with a query that looks like:
select *
from thisTable
where something=; DROP TABLE employees;
This is an odd example. But it does more or less show why it's dangerous. The first query will fail, but who cares? The second one will actually work. And if you have a table named "employees", well, you don't anymore.
Two characters in this case are sufficient to make an error in query and possibly reveal some information about it. For example try to use string ')480 and watch how your application will behave.
Although not much of an answer, this really doesn't fit in a comment.
Your code scans a table checking to see if a column value matches any pair of consecutive characters from a user supplied string. Expressed in another way:
declare #SearchString as VarChar(10) = 'Voot';
select Buffer, case
when DataLength( Buffer ) != 2 then 0 -- NB: Len() right trims.
when PatIndex( '%' + Buffer + '%', #SearchString ) != 0 then 1
else 0 end as Match
from ( values
( 'vo' ), ( 'go' ), ( 'n ' ), ( 'po' ), ( 'et' ), ( 'ry' ),
( 'oo' ) ) as Samples( Buffer );
In this case you could simply pass the value of #SearchString as a parameter and avoid the issue of the IN clause.
Alternatively, the character pairs could be passed as a table parameter and used with IN: where Buffer in ( select CharacterPair from #CharacterPairs ).
As far as SQL injection goes, limiting the text to character pairs does preclude adding complete statements. It does, as others have noted, allow for corrupting the query and causing it to fail. That, in my mind, constitutes a problem.
I'm still trying to imagine a use-case for this rather odd pattern matching. It won't match a column value longer (or shorter) than two characters against a search string.
There definitely should be a canonical answer to all these innumerable "if I have [some special kind of data treatment] will be my query still vulnerable?" questions.
First of all you should ask yourself - why you are looking to buy yourself such an indulgence? What is the reason? Why do you want add an exception to your data processing? Why separate your data into the sheep and the goats, telling yourself "this data is "safe", I won't process it properly and that data is unsafe, I'll have to do something?
The only reason why such a question could even appear is your application architecture. Or, rather, lack of architecture. Because only in spaghetti code, where user input is added directly to the query, such a question can be ever occur. Otherwise, your database layer should be able to process any kind of data, being totally ignorant of its nature, origin or alleged "safety".
I have the following code in which I'm using a variable to pass a list of values to multiple SQL statements (I can't save in a table as I don't have authority and don't want to have to maintain the list in all of the various SQL sections).
It works fine as long as all of the values are on a single line... but as I have so many values; I'd like to split it into multiple lines and use the Continuation Character '-'.
I'm running Oracle SQL Developer 2.1.1.64 against Oracle 10g (I also tried this in PL/SQL Developer and it failed there as well)
--=========================================
define subclasses = ('10-1010-10','10-1010-15','10-1010-20', -
'10-1010-25','10-1010-30') --- there are another 60 values...
select item from item_master where ((subclass) in &&subclasses);
Select Price from Item_prices where ((subclass) in &&subclasses);
--=========================================
I get the following error
ORA-01722: invalid number
01722. 00000 - "invalid number"
as it is parsing the code as
select item from item_master where ((subclass) in ('10-1010-10','10-1010-15',
'10-1010-20', -'10-1010-25','10-1010-30'))
...keeping the continuation code '-' in the SQL....tho it DOES go to the 2nd line of values.
If I remove the '-' ... it only processes the values on the first line and parses as
select item from item_master where ((subclass) in ('10-1010-10','10-1010-15','10-1010-20', )
... losing the second to nth line of values (and throwing errors as it ends w/ ',' and doesn't have the final ')'). How do I fix this?
You could do this:
column subc new_value subclasses
select q'[('10-1010-10','10-1010-15','10-1010-20',
'10-1010-25','10-1010-30')]' as subc
from dual;
Now &subclasses. will contain all the codes.
NB I used the q'[...]' quote syntax to avoid have to double up all the quotes in the data.
I noticed that you are trying to substitute a list of string variables into the select statement. You should rewrite your define statement to make it a single list of strings like this:
define subclasses = '''10-1010-10'',''10-1010-15'',''10-1010-20'', -
''10-1010-25'',''10-1010-30'''; --- there are another 60 values...
The - should be fine as a continuation character (see Oracle documentation here).
Now, when you execute your select statements you need to edit the WHERE clause so they are formatted so it will plug those values directly in there as written:
Select item from item_master where subclass in (&subclasses);
Select Price from Item_prices where subclass in (&subclasses);
This will end up being interpreted as if you had written:
Select item from item_master
where subclass in ('10-1010-10','10-1010-15','10-1010-20', '10-1010-25','10-1010-30');
If you have a lot of values though, you might run into limitations for substitution variables if you are using SQL*Plus (i.e. limited to 240 bytes per variable). In that case, you can either split the variables into multiple variables and concatenate them in the SELECT, or if you are in a PL/SQL environment, you can create variables that will hold the larger data size.