Crystal Report: IsNull equivalent for SQL Expression - sql

I want to filter out the data in my crystal report. Currently, I have the following formula in the Record Selection: isnull({T_TABLE.SOME_COLUMN}).
Apparently, if we use some functions in Crystal Report, it does not get converted to the SQL query (i.e. it will not add the SQL statement with something like T_TABLE.SOME_COLUMN IS NULL.
Since this checking is pretty basic, I want this condition to be pushed to the SQL statement that is generated because it should be faster to filter at database level rather than Crystal Report. Based on what I read, the possible way to push some condition to the SQL statement is to use the SQL Expression Fields. But I don't seem to be able to write T_TABLE.SOME_COLUMN IS NULL. It gives error : FROM keyword not found where expected.
Any idea how to solve this?
[EDIT]: The IsNull seems to be pushed when if it is isnull({T_TABLE.SOME_COLUMN}). But if it is some view, e.g. isnull({V_VIEW.SOME_COLUMN}), it does not get pushed.

The IsNull() function is actually pushed to the SQL query, with the condition that it is not compared to some value in the Crystal Report Record Selection formula.
So IsNull({T_TABLE.SOME_COLUMN}) is converted to SQL query T_TABLE.SOME_COLUMN IS NULL. But IsNull({T_TABLE.SOME_COLUMN}) = true won't.

Related

Dealing with filtered Pass Through Query in MS Access

I have a relatively complex SQL query (complex to run in Access) and want to run it in MS Access. It works with the pass-through query well but going forward I will face an issue that is related to a filter I apply in the query. I select the current report date within the where function. Below is a part of my query I try to handle ;
select LS.PID_FACILITY, LS.ASOF_DTE, LS.DATA_CYCLE_FLG, LS.CUST_ACC, LS.CUST_SMUN, LS.CUST_NME, LS.CUST_CTY,
WHERE LS.ASOF_DTE='19-SEP-22'
I do not want to change asof_dte filter manually everyday. If this was a normal access query I could join another table that includes only the current report date. But I cannot do it in a pass-through query. What is the alternative way to do it? I read something about creating variables or strings, but I could not relate them to my problem, since I am a beginner at creating such solutions.
Thank you all.
Well, two VERY intresting things here.
First, YES a great idea to include the date in the PT query. But, you don't want to change that date each time.
Soluton:
Add a paramter to the query, and then from Access code add that paramter. It is VERY easy to do this (one line of code!!! - don't adopt the zillion examples out there that has a boatload of ADO code - NOT required!.
However, BEFORE we start dealing with above?
A MUCH better and simple, less work way to approach this?
in place of stored procedure?
if possbile, create a view. and use that for the report.
Why?
Because you then get TWO VERY valuable bonus.
First, you can freely use the reports "where" clause, and it respects the where clause and STILL runs server side!!!
In other words, create a view for that existing query, but WITHOUT the date set in that view.
You then link to the view from access client side.
Now, to open (filter) the report, you can do this:
docmd.OpenReport "MyReport",acViewPreview,,"LS.ASOF_DTE='19-SEP-22'"
Now, of couse the above "where" clause can be a varible (string).
NOTE SUPER but SUPER careful here:
If you base the reprot on a pass-though query (that then uses the stored procedure), then the filter occures CLIENT SIDE!!!! (all rows will be returned and THEN filtered if you report is based on that stored procedure.
But, if you use a view?
The the filter makes it to the server side!!!!
While both the pass-through query or the "view" can be filtered with the above "open report" and the where clause we have above?
The view will still filter server side - the pass-though query will NOT!!!
Now, the 3rd way, is of course to build the stored procedure to accept a date parmater.
You then could do this:
with Currentdb.QueryDefs("MyPassThoughQueryGoesHere")
.SQL = "EXEC MyStoreProc " + "19-SEP-22"
END WITH
docmd.OpenReport "MyReport",acViewPreview
So, you CAN add and have a PT query and add a paramter as per above.
However, unless that stored procedure has some speical code, you are MUCH better off to create a view server side, base the reprot on that view, and simple pass + use the traditional "where" clause of the open report command. Even if that view has no filter, returns all rows in the table?
With the "where" clause of the open report command, ONLY those rows meeting that critera will be pulled down the network pipe.
So, say a invoice table with 1 million rows.
Create a view, link the view in access.
base report on that view.
Now, do this:
docmd.OpenReport "rptInvoice",,,"InvoiceNum = 134343"
The above will ONLY PULL down 1 row from the server. Even if the view has no filter and would return 1 million rows.
So, using a view is less work then creating the stored procedure.
But, you can modify the stored procedure to accept a paramter, and then as noted use the above example to modify the PT query you have, and THEN open the report.
I think overall, it is less work to use view. Furthermore, if you have a slow running report now?
Replace the query (move it) to sql server side. Get it working. Now link to that view (give it same name as what the client side query was in Access).
Now, EVEN if you had some fancy filter code in VBA, and used openReport with the "where" clause? It will now work, only pull the records down the network pipe, you get stored procedure performance without the hassles. and the date format and "where" clause for open report is access/VBA style - not sql server style SQL.
So, high recommend you try and dump the stored procedure and use a view (and EVEN better is any where clause works - not just one based on pre-defined parameters for the stored procedure - so you not limited to parameters)
. However, no big deal - the above "EXEC dbo.MyStoreProce " & strDate example would also work fine if you have a date parameter you wish to supply to the pass-though query.

PL/SQL Function call in ORACLE and VBA shows different Output

Facing very strange issue regarding PL/SQL function call from VBA and Output of same on Oracle SQL Developer. Both seems to vary by a lot. Please go through the attached screen shots. 1st Image shows the VBA output.
Here is the output which I get on ORACLE SQL Developer
More strange thing here is, This error I am facing only for few FSYM_IDs not all. For others its coming very much precise.
I did see the following question
Similar Question
There user had mentioned about hash joins but I haven't used any sort of hash joins at all.
I have used ADO and Range.CopyFromRecordSet to fetch data into excel. Executed the same exact query which is
select FSYM_ID, CURRENT_FY, ROUND(VALUATION_PB_HIGH,0), ROUND(VALUATION_PB_LOW,0) from table(PRICE2BV('07BR8Q-R'))
into excel and oracle sql developer.
I have updated the SQL Developer screenshot. Difference is in the particular years high and low value. I have highlighted that in the SQL developer output.
Additional things about Oracle PL/SQL functions are
Function returns data from global temporary table.
Variables used are of type number or varchar only.
Input to the function is identifier for the company only.
I have tried to retrieve output using table also but no use.
I have even tried the approach of GetRows mentioned on following link.
SQL Query output in VBA is different than in SQL Oracle
One thing I observed regarding recordset is that==> Values are different when I query from VBA and Oracle SQL Developer.
Please help me regarding same.

Cannot view the SQL portion of a query in ACCESS?

I am currently working on a project of replacing our old access database queries, but on one of them I am not able to view the actual SQL View.
Does anyone know a way to force the view or to export it somehow?
Error causing problem:
The SQL statement could not be executed because it contains ambiguous outer joins.
Note that I can view the Design View without issue but when I right click on the tab and select SQL View is when I get the error.
I did attempt what #LeeMac mentioned below but same error occurs:
EDIT:
This question is not like Ambiguous Outer Joins?
The OP on that question can actually see and edit their SQL.
My issues is that I cannot see or edit the SQL as the SQL View wont open.
Try executing the following VBA code from the Immediate Window (accessible using Ctrl+G) in the VBA IDE (open the IDE using Alt+F11):
?CurrentDb.QueryDefs("YourQuery").SQL
Replace YourQuery with the name of your query.
This should print the SQL code which comprises your query - you can then analyse the SQL to determine the cause of the error.
It's odd this error would arise when merely viewing the SQL content of the query definition.
It makes me think that the query is perhaps referencing a crosstab subquery which is actually the cause of the error, but which needs to be evaluated in order for MS Access to determine the columns available when viewing the design of the query in question.
Try this:
hit ctrl-g, and from immediate window type in this:
saveastext acQuery,"Name of query","c:\test\mysql.txt"
Access ordinarily doesn't allow you to save invalid queries, so it's strange you somehow got into this situation in the first place.
If you can copy the query, you can easily get to the SQL by changing the query to a passthrough query, either through the GUI or through VBA:
Dim q As DAO.QueryDef
Set q = CurrentDb.QueryDefs!Query1
q.Connect = "ODBC;"
Debug.Print q.SQL
Passthrough queries are not validated, so you can freely read and write anything you want as SQL in it.
Note that this is irreversible when done through VBA. You can only change it back to a normal query once you made the SQL valid again. If you do it through the GUI, you can just not save it, though.
I had this problem and the issue was that i had a subquery that calculated fields but did not actually have a table in it. for example it would calculate first and last day of last month which is 2 calculated fields, then it was the first query in a series of queries that were built off it and the last one wouldnt resolve sql as original poster indicated also gave the ambiguous join message as well as query needs input table (which was that first subquery). i put a table with 1 record in it but didnt use the record and it worked.... so it just a needs a table in it.

How to include 'NULL' value in Microsoft SQL server Report Builder

I would like to include NULL value from the database in Micorsoft SQL Server Report Builder 2012.
Problem:
Whenever I try to include NULL value in parameter drop-down list.. I can't sort by 'NULL' values in my report.
You mean like the Null values go last?
Well I had problems when I tried to order my results by Query or by hand (I mean, like selecting how to order in the tablix) because none of this would work at all.
It will result for sure if you use "Dynamic Order". :)
It's not too "Comfortable" to use it because when you run the report you will have to click in the column you will use as a reference to order your report and when it's done you will be able to sabe or print your report.
It would be great if it ordered the results by itself by just running the report but it won't work.
:) I hope I could help.

how to use common function in query expression?

I want to use the "split" function in a simple query on my SSRS 2008 report. However, I get an error "Query execution failed for dataset "SlsmRealNum". "Split" is not a recognized built-in function name". But it's listed as a common function (text) if I open up the Expression box on the query, so not sure why it's failing?
my simple select statement is:
select slsm_num, slsm_msid from Salesman where slsm_msid = split(User.UserID,"\").GetValue(1)
right now to get the report to work, I have one parameter (SlsmnNum) that has the Split expression in it (to get the MSID of the user) and then a 2nd parameter that uses the above query in the Dataset Salesrepum using the #SlsmnNum parameter as the MSID. I'd like to not have to have 2 parapmeters if possible and just get the actualy salesrep # in just one. Any help is greatly appreciated!
Your select statement is executed as SQL so the error you are getting is actually from SQL server. This may be where you are getting confused.
There are two components to SSRS - SQL Statements and Report Expressions. Typically, SQL statements are used to generate datasets by querying the database. Report expressions are used to organize, aggregate, and filter the dataset once obtained from the SQL database. Since the SQL statement is executed IN the SQL database, only the functions that are in the database are available. The code you posted is a SQL statement not a Report Expression.
For example, you can't take a Report Expression and expect it to work in SSMS? No, because they are two different entities with wholly different syntax and purpose. When it comes to using built-in SSRS functions inside a SQL statement it will not work, the database has no concept of what the built in User.UserId is and as such you must use a parameter to transport the value over to the SQL query. This is definition and purpose of a parameter and why they exist.
Split is a function in SSRS which is why you see it in your expression reference, however, it is not a function in SQL. The code you posted is SQL syntax, so I am betting that this is the SQL statement that you are using to obtain your dataset. Therefore the query fails since the SQL DB does not have a Split Function.
You can add this split function to your database and the code is located here: Split String in SQL. You could also use something along the following in your where clause, the following is your updated SQL statement.
SELECT slsm_num, slsm_msid from Salesman where slsm_msid = SUBSTRING(#UserId, PATINDEX('%\%', #UserId), LEN(#UserId))
You would set the #UserId parameter's value to an expression of User!UserID rather than specifying it in your select statement.
The SSRS expression examples have a function similar to what your code is trying to accomplish if you were wanting the same thing in the report side. The function you are looking for is InStr(). On your report side you could use something along the lines of:
=Parameters!User.Value.Substring(Parameters!User.Value.IndexOf("\")+1, Parameters!User.Value.Length-Parameters!User.Value.IndexOf("\")-1)
Expression examples can be found here: MSDN Expression examples.