I'm having one of those throw the computer out the window days.
I am working on a problem involving Crystal Reports (Version 10) and an Oracle Database (11g).
I am taking a view from the database that returns a string (varcahr2(50)) which is actually a number, when a basic SELECT * query is run on this view I get the number back in the format 000000000000100.00.
When this view is then used in Crystal Reports I can view the field data, but I can't sum the data as it is not a number.
I began, by attempting to using ToNumber on the field, to which Crystal's response was that the string was not numeric text. Ok fair enough, I went back to the view and ran TO_NUMBER, when this was then used in crystal it did not return any results. I also attempted to run TO_CHAR on the view so that I could hopefully import the field as text and then perform a ToNumber, yet the same as with the TO_NUMBER no records were displayed.
I've started new reports, I've started new views. No avail.
This seems to have something to do with how I am retrieving the data for the view.
In simplistic terms I'm pulling data from a table looking at two fields a Foreign Key and a Value field.
SELECT PRIMARY_KEY,
NVL(MAX(DECODE(FOREIGN_KEY, FOREIGN_KEY_OF_VALUE_I_NEED, VALUE_FIELD)), 0)
FROM MY_TABLE
GROUP BY PRIMARY_KEY
When I attempted to put modify the result using TO_NUMBER or TO_CHAR I have used it around the VALUE_FIELD itself and the entire expression, wither way works when the run in a SQL statement. However any TO_NUMBER or TO_CHAR modification to the statement returns no results in Crystal Reports when the view is used.
This whole problem smacks of something that is a tick box or equivalent that I have overlooked.
Any suggestions of how to solve this issue or where I could go to look for an answer would be greatly appreciated.
I ran this query in SQL Developer:
SELECT xxx, to_number(xxx) yyy
FROM (
SELECT '000000000000100.00' XXX FROM DUAL
)
Which resulted in:
XXX YYY
000000000000100.00 100
If your field is truly numeric, you could create a SQL Expression field to do the conversion:
-- {%NUMBER_FIELD}
TO_NUMBER(TABLE.VALUE_FIELD)
This turned out to be an issue with how Crystal Reports deals with queries from a database. All I needed to do was contain my SQL statement within another Select Statement and on this instance of the column apply the TO_NUMBER so that Crystal Reports would recognize the column values as numbers.
Hopefully this helps someone out, as this was a terrible waste of an afternoon.
Related
I do voluntary work at an animal shelter. We have an application which uses a SQL Server 2019 database. I have created a view that includes a varbinary(max) column. The value in this column is a picture, stored in hexadecimal-format. I would like to convert this Hex-value to a base64-binary file and add these to the view as an extra column.
I found the perfect solution for my situation in SQL Server : hex to base64. The example provided converts 1 single hex-value into 1 base64-value. I now need to add this solution to my view, but I'm not having any success.
The offered solution:
DECLARE #TestBinHex varchar(max), #TestBinary varbinary(max), #Statement nvarchar(max);
SELECT #TestBinHex = '0x012345';
SELECT #Statement = N'SELECT #binaryResult = ' + #TestBinHex;
EXECUTE sp_executesql #Statement, N'#binaryResult varbinary(max) OUTPUT', #binaryResult=#TestBinary OUTPUT;
SELECT
CAST(N'' AS XML).value(
'xs:base64Binary(xs:hexBinary(sql:column("bin")))'
, 'VARCHAR(MAX)'
) Base64Encoding
FROM
(SELECT #TestBinary AS bin) AS bin_sql_server_temp;
A simplified version of my view:
SELECT
a.cat_id, a.catname, s.cat_id,
s.stay_id, s.shelter_handler, s.shelter_kennel, s.picture
FROM
dbo.animal AS a
OUTER APPLY
(SELECT TOP 1 *
FROM dbo.shelterdata
WHERE a.cat_id = s.cat_id
ORDER BY s.stay_id DESC) AS S
WHERE
(a.cat_id IS NOT NULL) AND (s.leave_date IS NULL)
The view shows an overview of all cats currently present in the shelter (leave_date is NULL). The reason for the TOP 1 is that sometimes shelter animals get returned, and the application then assigns a new stay_id. To prevent duplicate values from the join, I only return the value of the most recent stay_id.
What I am trying to achieve: the second table (dbo.shelterdata) includes the picture, stored in hex value. I'd like to add a column Base64Encoding to the view which includes the converted value.
My attempts
I was successful in replacing the static value '0x012345' by a SELECT statement. But the way the solution is formatted, it only allows for one input value. So I had to restrict it with a WHERE clause. It is obvious to me that I need to make a subquery which inputs the hex value based on the unique cat_id. However, it has been many years since I worked with variable, so I'm struggling with the formatting of the statement.
My request
Does anyone have a suggestion how to build the conversion into the view?
Any assistance would be greatly appreciated.
After searching for a few more hours, I stumbled onto the solution. Maybe it will help someone else in the future. The solution is remarkably simple, as is often the case.
My view, mentioned above, is called dbo.shelter_view
select sv.picture,sv.cat_id,
cast('' as xml).value(
'xs:base64Binary(sql:column("sv.picture"))', 'varchar(max)'
) as Base64Encoding
from dbo.shelter_view as SV
I'm running Apex 19.2 and I would like to create a classical or interactive report based on dynamic query.
The query I'm using is not known at design time. It depends on an page item value.
-- So I have a function that generates the SQL as follows
GetSQLQuery(:P1_MyItem);
This function may return something like
select Field1 from Table1
or
Select field1,field2 from Table1 inner join Table2 on ...
So it's not a sql query always with the same number of columns. It's completely variable.
I tried using PL/SQL function Body returning SQL Query but it seems like Apex needs to parse the query at design time.
Has anyone an idea how to solve that please ?
Cheers,
Thanks.
Enable the Use Generic Column Names option, as Koen said.
Then set Generic Column Count to the upper bound of the number of columns the query might return.
If you need dynamic column headers too, go to the region attributes and set Type (under Heading) to the appropriate value. PL/SQL Function Body is the most flexible and powerful option, but it's also the most work. Just make sure you return the correct number of headings as per the query.
Situation is following:
I have identified sql injection attack vector, and have following information about target table:
It has six columns. (Identified using "order by").
I can see output of 3 of them (table is displayed). two seems kind of enum value (integer in database?), and one is a date. I have very strong suspicion that col #6 is date column.
I'm almost sure the database is oracle. (ROWNUM works and LIMIT gives error).
I don't have error messages (always generic text is returned - "something went wrong").
Frontend is PHP if that matters. But there might be middle layer between it and database (e.g. java service), so I'm not sure where the query is being constructed.
E.g. following search query works as expected:
test' AND ROWNUM <= 5 ORDER BY 6--
EDIT-FROM-HERE:
Ok after help from comments, following query works:
test' UNION ALL SELECT null,null,null,null,null,null FROM dual--
(I was missing FROM dual part. Thank you #kordirko very much!)
This query adds one empty record in the output table (it is visually visible), so I'm definitely on the right track!
Now following line also works:
test' UNION ALL SELECT null,null,null,n't',null,null FROM dual--
I correctly identified 4th column and now it displays uppercase(?) letter T where I expected it to appear. So far so good. But it gives error when I input any string longer than 1 char! So following gives an error:
test' UNION ALL SELECT null,null,null,n'test',null,null FROM dual--
I'm no expert in SQL injection, and especially ORACLE (though have experience with MsSql).
I think the problem is something unicode-ansi-whateverencoding-related. For other rows (selected by original query before my UNION ALL SELECT addition) the 4th column gives multi-character normal strings. But when I try to inject desired string, it only works if it's one character, and also misteriously displays it in uppercase. I think this must be some encoding problem. I just discovered I needed n prefix for unicode string after 1 hour of searching and struggling. Maybe some Oracle gurus can quickly spot what mistake do I have in my query?
I am using SQLManager Lite for firebird and it was impossible so far to write a query which would do an operation on char/varchar columns. Character set is win1252.
A query like
select * from Person where name = 'John'
won't return any results despite the fact that the record exists in the database. A similar query on a numerical column works just fine.
AM I am missing anything here?
Also, this query runs fine from my application. The only issue is that I would like to be able to run it within SQLManager Lite too. As a side note, values for char and varchar columns are not displayed properly within the same SQLManager Lite.
change to like
select * from Person where name like 'John'
Im new with JDBC, and while executing some query i get a result that is inconsistent.
If i execute this query in sql developer (connected to a Oracle DB) i get 4 results
SELECT *
FROM someTable1 some1
JOIN someTable2 some2 on (some1.some_id= some2.other_id)
WHERE some2.some_date LIKE '01/01/01' OR some2.some_date IS NULL
Then, i load this same query from a properties file in java and execute the query and get 0 results... anyone know why this is happening? I first suspect of the single quotes in the propertie value but i dont know...
Thanks in advance and excuse my poor english! :)
The query doesn't contain any special characters which could confuse Java, the properties loader or JDBC, so you should get exactly the same results in SQL Developer and with JDBC.
In fact, SQL Developer is written in Java, so it is using JDBC to execute the queries.
Print the query to the console before you execute it to make 100% sure the code executes the query that you have in mind.
Next, you should check the type of some_date. LIKE is only defined for string types (VARCHAR and similar), not for date/time types.
Oracle has a set of helper functions to build queries for date/time types, for example:
some_date = to_date( '01/01/2001','mm/dd/yyyy')
or
TRUNC(some_date, 'DAY') = to_date( '01/01/2001','mm/dd/yyyy')
The second query strips hours, minutes, seconds, etc. from the column and will compare only days, months and years.
Note: Always use 4-digit years to avoid all kinds of odd problems.