Does AdomdDataReader work with queries with no columns? - mdx

I'm currently trying to switch from using CellSet to using AdomdDataReader for a project, because I noticed that performance is significantly better with the latter.
So far it works great, with one exception: Queries that don't specify any columns will make the DataReader return false on the very first Read() call, implying that there are no rows to read.
Example 1 (can't be read via DataReader):
SELECT
{ } ON COLUMNS,
{ [Some].[Dimension].[Here] } ON ROWS
FROM CubeName
Example 2 (can be read via DataReader):
WITH MEMBER [Measures].[Dummy] AS NULL
SELECT
{ [Measures].[Dummy] } ON COLUMNS,
{ [Some].[Dimension].[Here] } ON ROWS
FROM CubeName
Example 1 doesn't work via AdomdDataReader (no rows), but works via CellSet and via SSMS and MDX Studio. Example 2 is a workaround that I'd like to avoid.
Is there any way to get this to work via AdomdDataReader or is this a known limitation?
/Edit: It turns out that the AdomdDataReader also skips columns that show only the [All] member of a dimension. Via CellSet (and via SSMS or MDX Studio), these columns are displayed, though.

Related

ms access query (ms access freezes)

I have this report and need to add totals for each person (the red circle)
existing report
new report
I cannot change the existing report so I export data from MS SQL to MS Access and create a new report there. I got it working for one employee but have trouble with a query which would for multiple employees.
This query extract data use as input:
SELECT [TIME].[RCD_NUM], [TIME].[EMP_ID], [TIME].[PPERIOD], [TIME].[PRUN], [TIME].[TDATE], [TIME].[PC], [TIME].[RATE], [TIME].[HOURS], [TIME].[AMOUNT], [TIME].[JOB_ID], [TIME].[UPDATED], [TIME].[UPDATED_BY], [TIME].[LOG_DATE], [TIME].[ORIGINAL_REC_NUM]
FROM [TIME]
WHERE ((([TIME].[EMP_ID])=376) And (([TIME].[TDATE])<=#12/31/2006# And ([TIME].[TDATE])>=#1/1/2006#) And (([TIME].[PC])<599));
this query populates the report:
SELECT *
FROM TIME1
WHERE RCD_NUM = (SELECT Max(RCD_NUM) FROM [TIME1] UQ WHERE UQ.PPERIOD = [TIME1].PPERIOD AND UQ.PC = [TIME1].PC);
the problem is if I remove EMP_ID from the first query like this
SELECT [TIME].[RCD_NUM], [TIME].[EMP_ID], [TIME].[PPERIOD], [TIME].[PRUN], [TIME].[TDATE], [TIME].[PC], [TIME].[RATE], [TIME].[HOURS], [TIME].[AMOUNT], [TIME].[JOB_ID], [TIME].[UPDATED], [TIME].[UPDATED_BY], [TIME].[LOG_DATE], [TIME].[ORIGINAL_REC_NUM]
FROM [TIME]
WHERE ((([TIME].[TDATE])<=#12/31/2006# And ([TIME].[TDATE])>=#1/1/2006#) And (([TIME].[PC])<599));
then the second query doesn't work and ms access freezes when running this query.
any help/idea please?
Caveat: I won't pretend to know the precise cause of the problem, but I have had to repeatedly refactor queries in Access to get them working even though the original SQL statements are completely valid in regards to syntax and logic. Sometimes I've had to convolute a sequence of queries just to avoid bugs in Access. Access is often rather dumb and will simply (re)execute queries and subqueries exactly as given without optimization. At other times Access will attempt to combine queries by performing some internal optimizations, but sometimes those introduce frustrating bugs. Something as simple as a name change or column reordering can be the difference between a functioning query and one that crashes or freezes Access.
First consider:
Can you leave the data on SQL Server and link to the results in Access (rather than export/importing it into Access)? Even if you need or prefer to use Access for creating the actual report, you could use all the power of SQL Server for querying the data--it is likely less buggy and more efficient.
Common best practice is to create SQL Server stored procedures that return just what data you need in Access. A pass-through query is created in Access to retrieve the data, but all data operations are performed on the server.
Perhaps this is just a performance issue where limiting the set by [EMP_ID] selects a small subset, but the full table is large enough to "freeze" Access.
How long have you let Access remain frozen before killing the process? Be patient... like many, many minutes (or hours). Start it in the morning and check after lunch. :) It might eventually return a result set. This does not imply it is tolerable or that there is no other solution, but it can be useful to know if it eventually returns data or not.
How many possible records are there?
Are the imported data properly indexed? Add indexes to all key fields and those which are used in WHERE clauses.
Is the database located on a network share or is it local? Try copying the database to a local drive.
Other hints:
Try the BETWEEN operator for dates in the WHERE clause.
Try refactoring the "second" query by performing a join in the FROM clause rather than the WHERE clause. In doing this, you may also want to save the subquery as a named query (just as [TIME1] is saved). Whether or not a query is saved or embedded in another statement CAN change the behavior of Access (see caveat) even though the results should be identical.
Here's a version with the embedded aggregate query. Notice how all column references are qualified with the source. Some of the original query's columns do not have a source alias prefixing the column name. Remember the caveat... such picky details can affect Access behavior.:
SELECT TIME1.*
FROM TIME1 INNER JOIN
(SELECT UQ.PPERIOD, UQ.PC, Max(UQ.RCD_NUM) As Max_RCD_NUM
FROM [TIME1] UQ
GROUP BY UQ.PPERIOD, UQ.PC) As TIMEAGG
ON (TIME1.PPERIOD = TIMEAGG.PPERIOD) And (TIME1.PC = TIMEAGG.PC)
AND (TIME1.RCD_NUM = TIMEAGG.Max_RCD_NUM)

MS Access SQL - UNION Returns Empty Set

I ran into a strange behaviour within Access. I basically have two predefined queries within my VBA-Project that are needed in different parts of the programm which are working fine.
Now I need a query which returns both result-sets as one. So my go to Solution was to create a new query combining the other two queries. Just like:
SELECT * FROM query1
UNION
SELECT * FROM query2;
Both queries have the same layout in their result. But if the result of query1 is empty and query2 has some records in its result I receive an empty result from the code above. The other way (empty result for query2 - several results for query1) it is delivering me a complete result.
I also tested the above code with the two queries switched. But the behaviour was the same. Same thing with UNION ALL.
What could be the issue here?
Edit: So, I did some further testing. The reason seems to be within query2. It can't even be unionized with itself. So if i try:
SELECT * FROM query2
UNION ALL
SELECT * FROM query2;
I again get an empty set. Same when i just use one field in the SELECT-part.
Edit2: OK it gets better. The Dataset is empty but within the table-view of the query result i have all the data within the filters of the columns. But if I do a Count(rowname) I get a 0 in return.
After two days of testing I was fed up and moved the code to another machine. Worked there. So after exporting it on the new machine and transferring it to my PC everything was functioning as it should. So I guess it was a problem related to the frontend I was using.
So if you run into smth. similar make sure that your project isn't corrupted in any way. (even if there aren't any errors shown by Access)

How to design my test automation

Here is my test scenario.
When a command line executes - lot of values are written to different tables in a db.
There are multiple command line options and many values/tables to be verified in the db. How should I go about designing the check for values in db?
What I done have so far -
execute the command
Connect to db
run the query particular to the command (this will be very specific to the command on what tables I need to look in)
from the dataset returned check if dt[row][col]="value i expect".
Advantage here is that I have to write less code as part of framework.
Downside of this is that I have to write more code when developing each tests, not streamlined and I may get column names wrong sometimes.
So I am trying to see if I streamline the check better. Something like declare a class (for a table)with columns as exposed properties. This way i wont get the column names wrong at least.
Is this the simplest approach ( for the long run? I want to write more reusable code). If not, what best way there is?
Is there a easy way to export tables/column values from db to a c# project file (as a class/code) so that I don't have to put everything in code again.
Let me know if any details are not clear or if I would like me to elaborate bit more on the details.
Thanks for looking.
I don't know of a standard approach for this problem, but I'll offer some ideas.
I usually find myself creating classes to represent tables to take advantage of compile-time checks, so I think that's a good way to go. You might want to look into Linq-to-SQL -- I think it can do a lot of this for you. I sometimes use ActiveRecord in Ruby for this purpose, even on C# projects, because development with it is very quick.
Alternatively, you might want to put the tests in text files:
Command:
command to execute
Expected Data:
SELECT column FROM table;
row name, column name, expected data
row name, column name, expected data
row name, column name, expected data
Expected Data:
SELECT column FROM table;
row name, column name, expected data
row name, column name, expected data
Then write a little code to load and parse your files, run the command, and compare the results. This would factor out only the things that change with each test, so I don't know if it can get much better.
Another idea is to try pulling common code into a base class and keep the varying code in subclasses. This design follows the Template Method pattern.
Example
class MyTest : CommandLineTest {
public String Command() { return "Command to execute"; }
public String DataRetrievalCommand() { return "SELECT column FROM table"; }
public DataResult[] ExpectedData() {
return [ new DataResult("column", "row", "value"), ...];
}
}
The superclass will use these methods to get the commands and values, but it will be the one doing all the actual work. Similar idea as the text files, but the test specification is kept in code.
Hope this helps or at least gets a few ideas flowing.

Groovy SQL Error - This ResultSet is closed

I am using Groovy's Sql object to perform queries on a postgres db. The queries are being executed as follows:
List<Map> results = sql.rows("select * from my_table")
List<Map> result2= sql.rows("select * from my_second_table")
I have a groovy method that performs two queries and then does some processing to loop through the data to make a different dataset, however, on some occasions I recieve a postgres exception "This ResultSet is closed" error.
having searched, I originally thought it might be to do with the issue here: SQLException: This ResultSet is closed (running multiple queries and trying to access the data from the resultsets after the fact) - however, we only seem to get the exception on quite high load - which suggests that it isnt as simple as the first dataset is closed on executing the second query as if this was the case I would expect it to happen consistently.
Can anyone shed any light on how Groovy's Sql object handles these situations or suggest what might be going wrong?
Groovy SQL is kind of a weird cat. Easy to use for simple stuff. If you have more complex scenarios you probably are better off using something else. IMHO
I first suggest doing one query, storing the results into a collection, do the second query and store the results in a collection and then do your operations between two collections rather than result sets. If you data is too large for that, find some way to store the data locally before you start doing your aggregation or whatever.
If you don't like that, you might need to checkout the GDK source code to get a better idea what is done with the Sql.getInstance() related to result sets etc. Then you can sidestep whatever land mine you are inadvertently stepping on.
Perhaps
List<Map> results = sql.rows("select * from my_table")
List<Map> result2= sql.rows("select * from my_second_table")
will not work even in plain Java (as already said in the answer you provided when second call is made on statement all resources dedicated during the previous call have to be released). As mentioned by #Todd W Crone Groovy can optimize resources, e.g. release them dynamically or don't release them depending on certain run.
Actually I've tried with only one query. E.g. I've tried to get ResultSet and then iterate through it, like this (don't mind the names of table and field, query is rather simple; and result is one row that contains one column due to LIMIT 1 clause):
def resultSet = sql.executeQuery("SELECT age FROM person WHERE id = 12345 LIMIT 1")
resultSet.next()
and got This ResultSet is closed error. Seems that Groovy optimizes resources and closes ResultSet immediately. I didn't look into the source code of Groovy SDK. I found that eachRow and other methods with closure-style handlers work fine and don't throw This ResultSet is closed error.
Perhaps, methods with closure-style handlers can help you. For example, look at except from the article where rows() method with closure is used:
String query = 'select id as identifier, name as langName from languages'
def rows = db.rows(query, { meta ->
assert meta.tableName == 'languages'
assert meta.columnCount == 2
// ...
})

CakePHP query additions in controller

I am migrating raw PHP code to CakePHP and have some problems. As I have big problems with query to ORM transformation I temporary use raw SQL. All is going nice, but I met the ugly code and don't really know how to make it beautiful. I made DealersController and added function advanced($condition = null) (it will be called from AJAX with parameters 1-15 and 69). function looks like:
switch ($condition) {
case '1':
$cond_query = ' AND ( (d.email = \'\' OR d.email IS NULL) )';
break;
case '2':
$cond_query = ' AND (d.id IN (SELECT dealer_id FROM dealer_logo)';
break;
// There are many cases, some long, some like these two
}
if($user_group == 'group_1') {
$query = 'LONG QUERY WITH 6+ TABLES JOINING' . $cond_query;
} elseif ($user_group == 'group_2'){
$query = 'A LITLE BIT DIFFERENT LONG QUERY WITH 6+ TABLES JOINING' . $cond_query;
} else {
$query = 'A LITLE MORE BIT DIFFERENT LONG QUERY WITH 10+ TABLES JOINING' . $cond_query;
}
// THERE IS $this->Dealer->query($query); and so on
So.. As you see code looks ugly. I have two variants:
1) get out query addition and make model methods for every condition, then these conditions seperate to functions. But this is not DRY, because main 3 big queries is almost the same and if I will need to change something in one - I will need to change 16+ queries.
2) Make small reusable model methods/queries whitch will get out of DB small pieces of data, then don't use raw SQL but play with methods. It would be good, but the performance will be low and I need it as high as possible.
Please give me advice. Thank you!
If you're concerned about how CakePHP makes a database query for every joined table, you might find that the Linkable behaviour can help you reduce the number of queries (where the joins are simple associations on the one table).
Otherwise, I find that creating simple database querying methods at the Model level to get your smaller pieces of information, and then combining them afterwards, is a good approach. It allows you to clearly outline what your code does (through inline documentation). If you can migrate to using CakePHP's find methods instead of raw queries, you will be using the conditions array syntax. So one way you could approach your problem is to have public functions on your Model classes which append their appropriate conditions to an inputted conditions array. For example:
class SomeModel extends AppModel {
...
public function addEmailCondition(&$conditions) {
$conditions['OR'] = array(
'alias.email_address' => null,
'alias.email_address =' => ''
);
}
}
You would call these functions to build up one large conditions array which you can then use to retrieve the data you want from your controller (or from the model if you want to contain it all at the model layer). Note that in the above example, the conditions array is being passed by reference, so it can be edited in place. Also note that any existing 'OR' conditions in the array will be overwritten by this function: your real solution would have to be smarter in terms of merging your new conditions with any existing ones.
Don't worry about 'hypothetical' performance issues - if you've tried to queries and they're too slow, then you can worry about how to increase performance. But for starters, try to write the code as cleanly as possible.
You also might want to consider splitting up that function advanced() call into multiple Controller Actions that are grouped by the similarity of their condition query.
Finally, in case you haven't already checked it out, here's the Book's entry on retrieving data from models. There might be some tricks you hadn't seen before: http://book.cakephp.org/view/1017/Retrieving-Your-Data
If the base part of the query is the same, you could have a function to generate that part of the query, and then use other small functions to append the different where conditions, etc.