SSIS: Debug SQLStatement in "Execute SQL" Task? - visual-studio

Our SSIS package has an Execute SQL Task that looks like below. As you can see it has parameters that are resolved in the Parameter Mapping tab. In this case, the four input parameters are User::SalesId, User::SalesEmp, User::CustomMsg, User::SalesCountry.
Question: how can I debug this call so that I know what SQL statement is being executed? Or at least know what the parameter values are at runtime.
I tried setting a breakpoint in OnPreExecuteEvent of the task, then I went to the Locals window. I was able to see the values of all the variables being used, which is fine. But I don't see the actual call of the stored procedure and its attached parameters.
Also, I can get the value of each individual using

I don't love this answer but it's an option.
Print statement doesn't work from an Execute SQL Task. At least, I can't seem to find an option to listen for the event.
As you are currently not returning a resultset I'd make use of them. Since you are using OLE DB Connection manager, and that is an ordinal based token system with the ? as the place holder, I am going to explicitly declare my variables and then populate them instead of the procedure call.
Fun note, I learned something today - do not declare your local variables as #p1, #p2 etc because the behind-the-scenes magic will also use those and you'll get duplicate declaration errors.
DECLARE #v0 int = ?
, #v1 int = ?
, #v2 int = ?
, #v3 int = ?;
SELECT #v0, #v1, #v2, #v3;
EXECUTE dbo.usp_RegisterSales #v0, #v1, #v2, #v3;
When that runs it will now generate a result set and we can just inspect the values afterwards.
General tab
Parameter tab
Result set tab
Putting it all together
The Script tasks simply emit any Read or Write variable's value to the output log via a RaiseInformation event
bool fireAgain = false;
string message = "{0}::{1} : {2}";
foreach (var item in Dts.Variables)
{
Dts.Events.FireInformation(0, "SCR Echo Back", string.Format(message, item.Namespace, item.Name, item.Value), string.Empty, 0, ref fireAgain);
}
The output is as shown
SSIS package "C:\Users\bfellows\source\repos\SO_Trash\SO_Trash\Package7.dtsx" starting.
Information: 0x0 at SCR Echo Back Pre, Scr Echo Back: User::EchoVariable->0
Information: 0x0 at SCR Echo Back Pre, Scr Echo Back: User::EchoVariable1->0
Information: 0x0 at SCR Echo Back Pre, Scr Echo Back: User::EchoVariable2->0
Information: 0x0 at SCR Echo Back Pre, Scr Echo Back: User::EchoVariable3->0
Information: 0x0 at SCR Echo Back Pre, Scr Echo Back: User::Variable->4
Information: 0x0 at SCR Echo Back Pre, Scr Echo Back: User::Variable1->3
Information: 0x0 at SCR Echo Back Pre, Scr Echo Back: User::Variable2->2
Information: 0x0 at SCR Echo Back Pre, Scr Echo Back: User::Variable3->1
Information: 0x0 at SCR Echo Back Post, Scr Echo Back: User::EchoVariable->4
Information: 0x0 at SCR Echo Back Post, Scr Echo Back: User::EchoVariable1->3
Information: 0x0 at SCR Echo Back Post, Scr Echo Back: User::EchoVariable2->2
Information: 0x0 at SCR Echo Back Post, Scr Echo Back: User::EchoVariable3->1
Information: 0x0 at SCR Echo Back Post, Scr Echo Back: User::Variable->4
Information: 0x0 at SCR Echo Back Post, Scr Echo Back: User::Variable1->3
Information: 0x0 at SCR Echo Back Post, Scr Echo Back: User::Variable2->2
Information: 0x0 at SCR Echo Back Post, Scr Echo Back: User::Variable3->1
SSIS package "C:\Users\bfellows\source\repos\SO_Trash\SO_Trash\Package7.dtsx" finished: Success.
If you have a longer term need for debugging/tracing/troubleshooting, I would create a table and stuff the aforementioned variables, one per row, + runtime metrics like #[System::StartTime] #[System::PackageName] #[System::ServerExecutionId] #[System::TaskID] and possibly #[System::MachineName]
Bam, now you have a reusable pattern that will keep track of parameter values across your packages for all time.

Related

IDL compilation doesnt return failure status

I dont have much experience with IDL but i need to fix a bug where in the compilation failure status needs to be returned to the calling script.
cat << ENDCAT > something.pro
PRINT, "Start"
PRINT, "Compiling functions needing early compile"
#do_early_func
PRINT, "Compiling remaining functions"
#do_other_func
PRINT, "Running: resolve_all"
resolve_all
EXIT
ENDCAT
setenv IDL_STARTUP something.pro
$IDL_DIR/bin/idl
The above content exists in a script called make_program which is called by another script called the build_script
The problem i am facing is that even if 'resolve_all' results in a compilation failure, the make_program always returns a true to the build_script making it think the compilation succeeded when it actually didnt. How can i return the failure status back to the calling script?
The EXIT routine has a STATUS keyword that can return the exit status of the script. So something like:
exit, status=status_code
To determine if RESOLVE_ALL completed correctly, you may need to do a CATCH block. The easiest way is probably to wrap RESOLVE_ALL in your own routine that has an ERROR keyword that returns whether the RESOLVE_ALL succeeded.
I'm not sure where I picked this up but you'll need two routines:
function validate_syntax_helper, routineName
compile_opt strictarr, hidden
catch, error
if (error ne 0) then return, 0
resolve_routine, routineName, /either, /compile_full_file
return, 1
end
and
function validate_syntax, routineName
compile_opt strictarr, hidden
oldquiet = !quiet
!quiet = 1
catch, error
if (error ne 0) then return, 0
; Get current directory
cd, current=pwd
o = obj_new('IDL_IDLBridge')
o->execute, '#' + pref_get('IDL_STARTUP')
; Change to current directory
o->execute, 'cd, ''' + pwd + ''''
; Validate syntax
cmd = 'result = validate_syntax_helper(''' + routineName + ''')'
o->execute, cmd
result = o->getVar('result')
obj_destroy, o
!quiet = oldquiet
return, result
end
You then call validate_syntax, which returns 1 when it can compile and 0 when it can't. I don't think this can be used from the IDL virtual machine since it uses execute, but maybe that doesn't matter to you. You'll have to manually run this on all your routines to be compiled instead of running resolve_all.

Magento foreach() orders getAllItems()

I am not sure why this loop is not working.
$orders = Mage::getSingleton('sales/order')->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter('created_at', array('from'=>$from, 'to'=>$to))
->addAttributeToSort('increment_id', 'ASC')
;
foreach ($orders as $item) {
$order_id = $item->increment_id;
if (is_numeric($order_id)) $order = Mage::getModel('sales/order')->loadByIncrementId($order_id);
if (is_object($order)) {
echo "> O: ". $order_id ."<BR>";
$items = $order->getAllItems();
echo ">> O: ". $order_id ."<BR>";
} else
die("DIE ". var_dump($order));
}
die("<BR> DONE");
The output:
...
...
>> O: 100021819
> O: 100021820
>> O: 100021820
> O: 100021821
The loop never finishes nor does it stop at the same order_id.?
It always fails at $order->getAllItems()
These orders are either pending, processing or complete.
Is there something I should be checking for with $order->getAllItems(), since that's were it's failing.
Thanks.
Jon, I assume the problem you're talking about is your script ending un expectedly. i.e., you see the output with a single >
> O: 100021821
but not the output with the double >>.
Because Magento is so customizable, it's impossible to accurately diagnose your problem with the information given. Something is happening in your system, (a PHP error, an uncaught exception, etc.), that results in your script stopping. Turn on developer mode and set the PHP ini display_errors to 1 (ini_set('display_errors', 1);) and check your error log. One you (or we) have the PHP error, it'll be a lot easier to help you.
My guess is you're running into a memory problem. The way PHP has implemented objects can lead to small memory leaks — objects don't clean up after themselves correctly. This means each time you go through the loop you're slowly consuming the total amount of memory that's allowed for a PHP request. For a system with a significant number of orders, I'd be surprised if the above code could get through everything before running out of memory.
If your problem is a memory problem, there's information on manually cleaning up after PHP's objects in this PDF. You should also consider splitting your actions into multiple requests. i.e. The first request handles orders 1 - 100, the next 101 - 200, etc.
What do you mean it fails?
By the look of the output it doesn't fail there as it outputs text either side of the call to getAllItems()
change:
$items = $order->getAllItems();
to:
foreach($order->getAllItems() as $orderItem) {
echo $orderItem->getId() . "<br />";
}
and see what happens.
The script could be ending on a different order ID each time if you have a low memory limit set on the server and it quits when it runs out of resources.

Codeigniter's XML-RPC shows no response data

I'm attempting to connect to an XML RPC server with no luck, I am getting an empty response with no debugging information whatsoever. I've switched on set_debug(), but still nothing.
Can anyone tell me why I am getting no response from the server, no error information and no debug information?
$this->load->library('xmlrpc');
$this->xmlrpc->set_debug(TRUE);
$this->xmlrpc->server('https://myurl.com/xmlrpc', 80);
$this->xmlrpc->method('login');
$request = array('param1', 'param2');
$this->xmlrpc->request($request);
echo 'Error: '. $this->xmlrpc->display_error() . '<br/>';
echo 'Response: '. print_r($this->xmlrpc->display_response(), true) . '<br/>';
Even if you type https:// in server method you are still connecting with server via http, look at 2nd parameter - the port you have set is 80.
Just in case.
I forgot to use:
$this->xmlrpc->send_request()
its best used in a conditional statement like:
if ( ! $this->xmlrpc->send_request())
{
echo $this->xmlrpc->display_error();
}
else
{
echo '<pre>';
print_r($this->xmlrpc->display_response());
echo '</pre>';
}

PHP4 including file during session

I am trying to put second language on my webpage. I decided to use different files for different languages told apart by path - language/pl/projects.ln contains Polish text, language/en/projects.ln - English. Those extensions are just to tell language files from other, the content is simple php:
$lang["desc"]["fabrics"]["title"] = "MATERIAŁY";
$lang["desc"]["fabrics"]["short_text"] = "Jakiś tam tekst na temat materiałów";
$lang["desc"]["services"]["title"] = "USŁUGI";
$lang["desc"]["services"]["short_text"] = "Jakiś tam tekst na temat usłóg";
And then on the index page I use it like so:
session_start();
if (isset($_SESSION["lang"])) {
$language = $_SESSION["lang"];
} else {
$language = "pl";
}
include_once("language/$language/projects.ln");
print $lang["desc"]["fabrics"]["title"];
The problem is that if the session variable is not set everything works fine and array item content is displayed but once I change and set $_SESSION["lang"] nothing is displayed. I tested if the include itself works as it should by putting print "sth"; at the beginning of projects.ln file and that works all right both with $_SESSION["lang"] set and unset.
Please help.
Can you test the return value of session_start() - if it's false, it failed to start the session.
Is it being called before you output anything to the browser? If headers were already sent and your error_reporting level is too low, you won't even see the error message.
Stupid, but - do you set value of $_SESSION['lang'] to valid value like "en"? Does the English translation load correctly when you use it as default value in else block instead of "pl"?
"Jakiś tam tekst na temat usłóg" -> "usług" :)
Can you tell us what does this one output:
if(session_start()) {
echo SID, '<br/>';
if(isset($_SESSION['lang'])) {
echo 'lang = "',$_SESSION['lang'], '"';
}
}
Session starts fine and accidentally I managed to fix it.
I renamed $_SESSION['lang'] to $_SESSION['curr_lang'] and it now works allright. It seams like it didn't like the array and session variable having the same name (?).

How can I get forking pipes to work in Perl on Windows?

I'm trying to port a Perl script over from Unix to Windows but am having a near impossible time getting it to work due to the unsupported forking pipes in the open function. Here's the code:
sub p4_get_file_content {
my $filespec = shift;
return 'Content placeholder!' if ($options{'dry-run'});
debug("p4_get_file_content: $filespec\n");
local *P4_OUTPUT;
local $/ = undef;
my $pid = open(P4_OUTPUT, "-|");
die "Fork failed: $!" unless defined $pid;
if ($pid == 0) { # child
my $p4 = p4_init();
my $result = undef;
$result = $p4->Run('print', $filespec);
die $p4->Errors() if $p4->ErrorCount();
if (ref $result eq 'ARRAY') {
for (my $i = 1; $i < #$result; $i++) {
print $result->[$i];
}
}
$p4->Disconnect();
exit 0;
}
my $content = <P4_OUTPUT>;
close(P4_OUTPUT) or die "Close failed: ($?) $!";
return $content;
}
The error is:
'-' is not recognized as an internal or external command,
operable program or batch file.
Does anyone know how to make this work? Thanks!
Mike
I know it's not a direct answer to your question, but it looks like you're scripting something on top of Perforce in Perl? If so you might find an existing library does what you want already and save yourself a lot of headaches, or at least give you some sample code to work from.
For example:
P4Perl
P4::Server
P4::C4
EDIT: Now that I know what you're doing I'm guessing you're trying to port p42svn to Windows, or rather make it compatible with Windows at least. See this thread for a discussion of this exact issue. The recommendation (untested) is to try the code samples listed at http://perldoc.perl.org/perlfork.html under "Forking pipe open() not yet implemented" to explicitly create the pipe instead.
It's not going to work as-is. You'll need to find another method to accomplish what it's doing. It doesn't look like there's that burning a need for the fork-pipe, but it's hard to tell since I don't know what a p4 is and a lot of your code is being lost to angle bracket interpretation.

Resources