Wednesday, March 7, 2012

Programmatically Accessing an SQLDataSource with a "SELECT COUNT(*)" query.

I've found example code of accessing an SQLDataSource and even have it working in my own code - an example would be

Dim datastuff As DataView = CType(srcSoftwareSelected.Select(DataSourceSelectArguments.Empty), DataView)

Dim row As DataRow = datastuff.Table.Rows(0)
Dim installtype As Integer = row("InstallMethod")
Dim install As String = row("Install").ToString
Dim notes As String = row("Notes").ToString

The above only works on a single row, of course. If I needed more, I know I can loop it.

The query in srcSoftwareSelected is something like "SELECT InstallMethod, Install, Notes FROM Software"

My problem lies in trying to access the data in a simliar way when I'm using a SELECT COUNT query.

Dim datastuff As DataView = CType(srcSoftwareUsage.Select(DataSourceSelectArguments.Empty), DataView)
Dim row As DataRow = datastuff.Table.Rows(0)
Dim count As Integer = row("rowcnt")

The query here is "SELECT COUNT(*) as rowcnt FROM Software"

The variable count is 1 every time I query this, no matter what the actual count is. I know I've got to be accessing the incorrect data member in the 2nd query because a gridview tied to srcSoftwareUsage (the SQLDataSource) always displays the correct value.

Where am I going wrong here?


The following should work.

Dim datastuffAs System.Data.DataView =CType(srcSoftwareUsage.Select(DataSourceSelectArguments.Empty), System.Data.DataView)

Dim drAs System.Data.DataRow = datastuff .Table.Rows(0)

Dim mycountAsString = Convert.ToInt32(dr("rowcnt")).ToString()

'Label1.Text = mycount

|||

Hi there,

Aren't you getting the row count from your SELECT COUNT query (1 row obviously)? Instead of getting the result value from that query?

gonzzas

|||

It's very similar to what I've tested out, but that exact code will show that mycount = "1" instead of the actual value.

What is interesting is the GridView control I set up on the test page is outputting the correct result.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="srcSoftwareUsage" Width="527px">
<Columns>
<asp:BoundField DataField="rowcnt" HeaderText="rowcnt" ReadOnly="True" SortExpression="rowcnt" />
</Columns>
</asp:GridView>

Now, it's obviously accessing the column named rowcnt. I can debug my code and manually look at the column values in DataView.Table.Rows(0) and it shows the value 1 and nothing more.

|||

Yes, I can use either code to get the correct count from my query. What is your SqlDataSource code?

Here is what I tested:

Dim dvAs System.Data.DataView =CType(SqlDataSource2.Select(DataSourceSelectArguments.Empty), System.Data.DataView)

Dim rowAs System.Data.DataRow = dv.Table.Rows(0)

' For Each row As System.Data.DataRow In dv.Table.Rows

Dim mycountAsString = Convert.ToInt32(row("rowcnt")).ToString()

Label2.Text = mycount

' Next

|||

Murphy's Law probably applies as I didn't give you thecomplete story - I naively thought this part shouldn't matter as it'sthe table output is identical.

It appears to be my sql query.

I'm not actually looking for the count of rows in the Software table, but I'm looking for the count of times a particular row in Software is referenced by 2 other tables - RoleSoft and TeamSoft

With my simple query above, both the code and GridView worked. With this one - the GridView works, the code doesn't.

SELECT COUNT(*) AS rowcnt FROM (SELECT Role, Software FROM RoleSoft WHERE (Software = @.Id) UNION ALL SELECT Team, Software FROM TeamSoft WHERE (Software = @.Id)) AS derivedtbl_1

I thought it was a moot point as the table output appears identical from each query. Obviously I'm wrong. I'm imagining the derivedtbl_1 is probably where I'm getting bogus data in the code.

1> SELECT COUNT(*) AS rowcnt FROM (SELECT Role, Software FROM RoleSoft WHERE (Software = 2) UNION ALL SELECT Team, Software FROM TeamSoft WHERE (Software = 2))
AS derivedtbl_1
2> go
rowcnt
----
3

(1 rows affected)
1> SELECT COUNT(*) as rowcnt FROM Software
2> go
rowcnt
----
8

(1 rows affected)

|||

Bah. I figured it out. It wasn't even the SQL statement. I had updated the @.Id parameter in the srcSoftwareUsage_Selecting event handler and I misused a global variable. It kept setting @.Id to 1 and the count for that Id was always 1.

Now I feel stupid for wasting your time and mine on this. Thanks for the help, though.

Programmatically Access The ExecuteProcessTask

Hi all,

I am trying to programmatically create an Execute Process Task in an SSIS package.

So far, I have the following:

Private package As Package
Dim th As TaskHost = TryCast(package.Executables.Add("STOCK:ExecuteProcessTask"), TaskHost)
th.Name = "Execute Process Task"
th.Description = "Execute Process Task"

That will get me the ExecuteProcessTask in my package that I want. But now, I would like to set the properties of it (i.e., the executable and arguments)

Basically, my IDE does not have any idea what an "ExecuteProcessTask" is. After lots of research, I cannot find out which assembly I need to reference in order to gain access to this object. In addition, whenever I try to Import the assembly that I think it is (i.e. Microsoft.SqlServer.ExecProcTask, or Microsoft.SqlServer.Dts.Tasks.ExecuteProcess), none of them work. I can see in my Assembly Cache that the .dll is registered correctly ...

What is going on?
What do you mean "none of them work"? When you set a reference to the Microsoft.SqlServer.ExecProcTask.dll then the code below should work.

Code Snippet

Dim execProc As Microsoft.SqlServer.Dts.Tasks.ExecuteProcess.ExecuteProcess = CType(th.InnerObject, Microsoft.SqlServer.Dts.Tasks.ExecuteProcess.ExecuteProcess)
execProc.Executable = "executable.exe"
execProc.Arguments = "/arguments"

|||Really, my problem is that I can't access the assembly that I need.

Basically, I need access to the Microsoft.SqlServer.Dts.Tasks.ExecProcTask assembly-

But, when I try to add a reference to it, I do not see it. In addition, with the interface in SSIS, I cannot "browse" for the assembly.

The only assembly that shows up in Intellisense is Microsoft.SqlServer.Dts.Tasks.ScriptTask

I am editing a script task- so what good is a script task if I can't access the assemblies I need?

What can I do?

|||Ah, you need to copy it from C:\Program Files\Microsoft SQL Server\90\DTS\Tasks to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727. Then it will show up in your References.
|||Graahhhhh!! I just came up with that idea, tried it out and it worked- graahh-- wasted so much time and was so frustrated by that yesterday because of something so simple- I hate that!

Programmatically aborting a package

Can a package executed from code be aborted in code? The Package class has an Execute() method but no Abort() method. Clearly the debugger can stop a package at any point, so it must be possible somehow.

Are you trying to capture an error and then halt? If so, there's always the FireError event that can be thrown.|||

JeffJohnsonMVPVB wrote:

Can a package executed from code be aborted in code? The Package class has an Execute() method but no Abort() method. Clearly the debugger can stop a package at any point, so it must be possible somehow.

You're right, the debugger can do that but it might be a misnomer to think that that is the same as aborting from within thw package.

I presume that your abort code would be conditional so I would suggest that the best way to achieve what you want is to use conditional precedence constraints. If you need any help with those, feel free to reply.

-Jamie

|||

Okay, I need to expound. I have created a Windows service that executes SSIS packages. Many of these are long-running, perhaps for hours. If an operator realizes that something is wrong after submitting a package, I'd like to allow him to send a cancel request to the service and then have the service stop the package. What I do NOT want to do is code every single precedence constraint to check for an "abort" flag (and I'm not sure I'd even know how to set such a flag once the package has started without putting an MSMQ task or the like between each executable--yuck!). Could I simply kill the thread that is executing the package? That seems "dirty," and I was hoping for a cleaner method.

|||

I've taken a look at the application class (http://msdn2.microsoft.com/en-us/library/microsoft.sqlserver.dts.runtime.application_members.aspx) and the package class (http://msdn2.microsoft.com/en-us/library/microsoft.sqlserver.dts.runtime.package_members.aspx) and I don't see anything in there that would help.

I can understand why. An executing SSIS package is meant to be a batch/unattended process - once its running you just leave it to get on with it. I fear killing the process might be the way to go.

If you didn't want to put a conditional precedence constraint onto every executable then another option might be to put the executable that conditionally "kills" the package into the package container's OnPostExecute eventhandler. This *could* potentially be a little bit more "graceful" about it than just killing the process. Might be worth a try.

-Jamie

|||

There is a cleaner method. Call RunningPackage.Stop().|||

If your service is starting processes asynchronously your best bet is track the process id. The service could check periodically if the process had ended and "forget" the process if it had. That would give you a way to track what was currently running as well as select a process to kill.. If you want something intelligent in your logging, just have the service write to whatever you use for logging once the process has gone away. Maybe something like *** Operator Canceled ***|||

jaegd wrote:

There is a cleaner method. Call RunningPackage.Stop().

Does this work for file system based packages executed from command line dtexec or otherwise?|||

That looks perfect. I should've scanned the class library reference more thoroughly. I'll try to remember to let everyone know how it works.

(Clearly I don't know how to use the quoting feature, sorry.)

|||

Follow-up question: does anyone know if SSIS raises any particular events when RunningPackage.Stop is called? I could trap these events in my custom tasks and fail them cleanly if so.

|||

Yes the SSIS runtime does signal an event when RunningPackage.Stop() is called. You can get at that event by polling periodically -- call to FireQueryCancel() in a custom task, let's say, at strategic points.

If you don't want to poll, you could wrap the the system variable System::CancelEvent in a SafeHandle and wait for the event to be signalled. That also works.

SSIS stock tasks vary at the frequency which they check if the package's Cancel event has been signalled, but they do check it periodically (no, its not documented the frequency at which the runtime check's the cancel event's state).

|||

RunningPackage.Stop() works on package invoked by any "mechanism", since its the same runtime. That includes command line, BIDS, custom invocation util (whatever you can dream up, e.g. web service, windows service), not to mention in-process or out-of-process package executions via Execute Package tasks.

Programmatic way to replace partition DSV Table bindings with Query Bindings

I'm trying to programmatically replace all my partitions' DSV table bindings with query bindings.

In the partitions manager, when creating a new partition that's restricted via a query binding, the wizard manages to pull a default query from the DSV definition. Is there a way to do this programmatically? The closest thing I could find in the object model is the "Schema" property, but this isn't what I need.

I am pretty sure anything you can do in XMLA is possible to do through AMO.

The easiest way for you to figure out what classes and properties or methods to use is to use AMOBrowser sample application. It shows you the real hierachy of AMO objects.

For instance, using that application I was able to figure out that partition has a source object and then simple search for "partition.source" brought me to this aricle http://msdn2.microsoft.com/en-gb/library/ms345091.aspx

Where I discovered following code sample

static void CreateInternetSalesMeasureGroupPartitions(MeasureGroup mg)
{
Partition part;
part = mg.Partitions.FindByName("Internet_Sales_184");
if ( part != null)
part.Drop();
part = mg.Partitions.Add("Internet_Sales_184");
part.StorageMode = StorageMode.Molap;
part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactInternetSales] WHERE OrderDateKey <= '184'");
part.Slice = "[Date].[Calendar Year].&[2001]";
part.Annotations.Add("LastOrderDateKey", "184");

Edward.
--
This posting is provided "AS IS" with no warranties, and confers no rights.

|||

Thanks for the tip, Edward. I still haven't found the class that exposes the DSV's query binding (which I would use when generating a new partition's query binding), so I suppose I might have to do this manually.

The Annotations property looks pretty useful though, thanks!

Programmatic synchronizing and metadata

Hello,
I created a subscription programmatically so I have the
CreateSyncAgentByDefaut property = false. Do I have to do some additional
functions to work with and clean up the subscription metadata.
Thanks for your help.
When your subscription is deployed merge replication will fix your database
to replicate to it. It will automatically clean up metadata as it no longer
needs it.
Hilary Cotter
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"Car" <Car@.discussions.microsoft.com> wrote in message
news:76F2D1C8-653B-4DD9-BAF9-3842221369E4@.microsoft.com...
> Hello,
> I created a subscription programmatically so I have the
> CreateSyncAgentByDefaut property = false. Do I have to do some additional
> functions to work with and clean up the subscription metadata.
> Thanks for your help.
>

programmatic rendering of multipage report

Hi,
I have created a multipage report (having almost 40 pages). I need to
render this report programmatically.
Is there any way to get the report pages as and when required (i.e.
when user clicks on <next> button).
I am able to render single page report using render() method. How to do
so for multipage report.
regards,
Sachin.What are you rendering it as? Image, HTML?
For an Image type you can specify the start page as part of the DeviceInfo.
Craig
"sachin laddha" <sachinladdha@.gmail.com> wrote in message
news:1142572855.966655.266270@.v46g2000cwv.googlegroups.com...
> Hi,
> I have created a multipage report (having almost 40 pages). I need to
> render this report programmatically.
> Is there any way to get the report pages as and when required (i.e.
> when user clicks on <next> button).
> I am able to render single page report using render() method. How to do
> so for multipage report.
> regards,
> Sachin.
>|||Hi,
I need to render it as HTML and PDF. Also Is it possible to find out
number of report pages in advance.
regards,
sachin.|||http://groups.google.com/group/microsoft.public.sqlserver.reportingsvcs/tree/browse_frm/thread/5a73412801f5ba54/f63ce6b85e448735?rnum=1&hl=en&q=%22Oleg+Yevteyev%22+pages&_done=%2Fgroup%2Fmicrosoft.public.sqlserver.reportingsvcs%2Fbrowse_frm%2Fthread%2F5a73412801f5ba54%2F41e4ed35916811eb%3Flnk%3Dst%26q%3D%22Oleg+Yevteyev%22+pages%26rnum%3D8%26hl%3Den%26#doc_ac075ac1383673e8
That is for HTML4.0 rendering
Hope it helps.
--
Oleg Yevteyev,
San Diego, CA
It is OK to contact me with a contracting opportunity.
"myfirstname"001atgmaildotcom.
Replace "myfirstname" with Oleg.
--
"sachin laddha" <sachinladdha@.gmail.com> wrote in message
news:1142578108.796952.163040@.z34g2000cwc.googlegroups.com...
> Hi,
> I need to render it as HTML and PDF. Also Is it possible to find out
> number of report pages in advance.
> regards,
> sachin.
>

Programmatic Rendering C# - passing Oracle credentials

What am I doing wrong here? I am trying to programmatcially run a report that
uses an Oracle stored procedure where the Oracle credentials would be
prompted if I ran interactively. The program (C#) compiles OK but I get an
'Object reference not set to an instance of an object' error when assigning
the credential property. The report runs interactively and I can
programmatically pass other parameters other than oracle credentials.
DataSourceCredentials[] credentials = new DataSourceCredentials[1];
credentials[0].DataSourceName = "MyDataSource";
credentials[0].UserName = "MyUser";
credentials[0].Password = "MyPassword";
data = _rs.Render("/MyFolder/MyReport","PDF", null, null, returnValues,
credentials , null, out encoding, out mimeType, out parametersUsed, out
warnings, out streamIds);
Any help appreciated.Sorry - just spotted it , I was missing a
credentials[0] = new DataSourceCredentials();
prior to assigning properties
"Joe" wrote:
> What am I doing wrong here? I am trying to programmatcially run a report that
> uses an Oracle stored procedure where the Oracle credentials would be
> prompted if I ran interactively. The program (C#) compiles OK but I get an
> 'Object reference not set to an instance of an object' error when assigning
> the credential property. The report runs interactively and I can
> programmatically pass other parameters other than oracle credentials.
> DataSourceCredentials[] credentials = new DataSourceCredentials[1];
> credentials[0].DataSourceName = "MyDataSource";
> credentials[0].UserName = "MyUser";
> credentials[0].Password = "MyPassword";
> data = _rs.Render("/MyFolder/MyReport","PDF", null, null, returnValues,
> credentials , null, out encoding, out mimeType, out parametersUsed, out
> warnings, out streamIds);
> Any help appreciated.