Reporting Services - Determine whether or not Stored Procedure returns garbage fields - stored-procedures

I have to develop a report against Sybase and I am calling a stored procedure for the dataset using an exec statement in a text query.
This stored procedure, instead of returning no records when there are none available, returns a table with a different column structure than that which is returned when records are available.
This causes all of my fields to display #ERROR. Is there a way to determine that the data set is going to return this garbage row so that I can hide the rows that are effected and handle the error?
Thanks so much for your help.
Frank

The solution for this is to check the IsMissing property on the dataset field:
Set the row's "Hidden" property to -
=IIF(Fields!FieldThatShouldBeThere.IsMissing,true,false)
Frank

Related

How to get last UpdateDate/sysLoadDatetime on records as part of result when executing a stored procedure

Hi I'm pretty much a beginner in SQL, but I would like to know if there is a way to know how old are the records contained in the stored procedure.
For example, if I execute a stored procedure, is there an extra statement that I can add to be able to see this last update date on each row?
When I run the stored procedure, it doesn't have a column that shows that information, but at least I would like to know how old is the data that is displaying.

Delete row from DBGrid only

I have a DBGrid that is updated on a button click. Once updated I have it check each row vs an XML file. If the fields in that row match the data in the XML file, I want to delete that row from the dbgrid only.
The DBgrid is loaded from ADOconnection / Query / Datasource . The main connection is to a DB which is linked to an excel file. The XML file is just a report we get each month. Normally we have to check to make sure all the machines on the excel file is also on the report given to us.. With hundreds of machines I am trying to auto detect any difference.
but I cant figure out how to delete the row in the grid only when it finds a match Thus only the non-Matched items are in the grid.
You can't delete rows from a DBGrid. You delete them from the dataset to which the DBGrid is connected. A DBGrid simply displays the data from a dataset. If you want the row deleted, delete it from that dataset using it's .Delete method.
After reading the edit you made, it looks to me like you should be loading the query data into a TClientDataSet (CDS), and then attaching that CDS to the DBGrid's DataSource. You can then do whatever you want to that CDS without affecting the original data, as long as you don't call the CDS's ApplyUpdates method.
What Ken White says in his answer is 100% correct, but I think there is something else
maybe worth pointing out, especially as you mention XML.
Unlike some other TDataSet descendants, both TClientDataSet and the more modern FireDAC datasets implement the UpdateStatus
property of the dataset and this reflects what has happened to the current record
in the dataset - see the Online Help for details. It is an enumeration [1] declared as
type
TUpdateStatus = (usUnmodified, usModified, usInserted, usDeleted);
You say you want to compare the records with what you have in an XML file and delete
the records which have not been updated "from the DBGrid", which as Ken has said is
not meaningful per se.
However there is another way of going about what you seem to want. If you can load the
data displayed in the dataset feeding the grid from the XML file. then you know
that until you update the dataset, the records must match the XML. So, once the
records have been updated in your app, rather than comparing all the records in the dataset
with their XML counterparts, you could simply delete (from the dataset) the records
whose UpdateStatus is usUnmodified. This is trivial to do using a method like this:
procedure TForm1.DeleteUnmodifiedRecords;
begin
ClientDataSet1.DisableControls;
try
ClientDataSet1.First;
while not ClientDataSet1.Eof do begin
if ClientDataSet1.UpdateStatus = usUnModified then
ClientDataSet1.Delete
else
ClientDataSet1.Next;
end;
finally
ClientDataSet1.EnableControls;
end;
end;
and this will, of course, remove the records from the DBGrid.
Of course, this assumes that you can load the XML data into a TClientDataSet
or a FireDAC dataset, eithe directly or by transforming the XML into a form that
either of these can load using a TXmlTransform component but I won't go
into the details of that here.
[1]: A point to beware of is that usModified does not seem to be the exact logical negation of usUnmodified. This has the slightly surprising consequence that if you
apply a StatusFilter of [usModified] to a CDS, records that have been changed can appear twice, once in their original form and once in their changed form - see fig 6.5 of Cary Jensen's "Delphi in Depth: ClientDataSets", 1st edition.
One option to make rows/records vanish from a dbGrid and other data aware controls is to use the TDataSet's OnFilterRecord and return false for rows you no longer want seen. It does not have any effect on the underlying data - it just filters out what is visible.
procedure TDM1.FDQueryTopicListFilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
// Check if the row should be shown - set Accept to true if it should, false if not
end;

db2 can you change cursor resultset in same stored procedure?

I have a stored procedure and which selects data from the database using
DECLARE cursor1 CURSOR WITH RETURN for SELECT...
OPEN cursor1
At this point I would like to delete and change records in the resultset in the same stored procedure. I cannot make these changes in the select.
Can this be done?
I have seen
DELETE WHERE CURRENT OF cursor1
but Data Studio does not like the syntax and underolines 'OF' as an error. I believe the version of Data Studio is only a couple of months old.
Thanks for any help or guidance.
You cannot change the result set without modifying the table itself. When issuing DELETE or UPDATE WHERE CURRENT OF you are actually deleting or updating rows in the underlying table.
Using WHERE CURRENT OF implies looping over the rows in the result set. Note that once you change the cursor position, the new position will be returned to the caller. In other words, after you consume the result set in the procedure itself, you will need to open the cursor once again in order to return the result set to the caller.

pyodbc return multiple cursors from stored procedure with DB2

I have a python program that calls a stored procedure from db2 database. I am using results = cursor.fetchall() to process the results of my stored procedure. However, my stored procedure returns two cursors. results only contains the first one. I need a way to loop through as many cursors as I want. I was hoping fetchmany() would be my answer but it is not.
I need to be able to do multiple result sets as the program I am writing can only call one stored procedure. It would take a lot to go back and make it to be able to call two. Besides with one of these things I need to make 10 cursors return. Everything is dynamic, so the application doesn't know what procedure it is running, it just gets the data and spits it into excel not knowing the meaning. I need one cursor for the data, and the other cursors for different types of counts and totals.
I am looking for a built in function to do this, or maybe even a different library because I have done my share of googling and it looks like pyodbc does not do this for DB2. DB2 is a requirement.
Use the nextset() method of the cursor: https://github.com/mkleehammer/pyodbc/wiki/Cursor#nextset
Sample code:
# fetch rows from first set
rows = cursor.fetchall()
# process first set rows here
# advance to next result set
while (cursor.nextset()):
# fetch rows from next set, discarding first
rows = cursor.fetchall()
# process next set rows here
nextset() will return True if additional result sets are available, and subsequent cursor fetch methods will return rows from the next set. The method returns None if no additional sets are available.
Just a small simplification for the record:
while True:
rows = cursor.fetchall()
# process all result sets in the same place
if not cursor.nextset():
break

Benefit of using DBComboBox over CombBox?

So I'm messing around with a new project in Delphi 2009 and the default components that can be dropped onto a form for accessing data consist of a SQLConnection, DataSource and SQLQuery. If I add a simple select to the query component, say:
select name from customers
and then drop a DBComboBox on the form and link it up with the DataSource I get a single record in the combo box. After using Google for half and hour to figure out what I was doing wrong it looks like you have to manually add some code to your project which loops through the dataset and adds all the records to the drop down box. Something like:
while not SQLQuery.eof do
begin
DBComboBox.items.add(SQLQuery.fieldbyname('name').asstring);
SQLQuery.next;
end;
And that actually sort of works, but then you get a list in the drop down which you can't actually select anything from. Regardless of the result though I'm wondering why would you even use a DBComboBox if you have to manually add the result of your query to it? Seems to me that if it doesn't automatically populate the db combo box with the result of the query then we might as well be using a non-data-aware component like tcombobox.
I guess what I'm asking is why does it work this way? Isn't the purpose of data aware drag-and-drop controls to minimize the amount of actual written code and speed development? Is there a method that I'm missing that is supposed to make this easier?
A TDBComboBox doesn't get its list of values from the database; it gets its current value from the database. Link it to a field in your dataset, and when you change the active record, the combo box's current value will change. Change the combo box's current value, and the corresponding field's value will change.
If you want to get the list of values from the database as well, then use a TDBLookupComboBox.
This is all covered in the help:
Using TDBListBox and TDBComboBox
Displaying and Editing Data in Lookup List and Combo Boxes
Defining a Lookup List Column
I think you want the TDBLookupComboBox because that allows you to lookup from a list of items where the list comes from a dataset.
In the TDBComboBox, the list is just a TStrings manually filled with data.
--jeroen
DbCombox is a dbaware version of the standard combobox component.

Resources