When to use environment variable or command line parameter? - scripting

When to use environment variable or command line parameter?
I think there are two ways to pass parameters to another process
in a script ,environment variable and command line parameters.
Thus,in which condition we choose one instead of another?

In most of the scripts I write, I allow both with the command line parameters taking preference.
This is to allow 'lazy' users who want to set'n'forget the parameters to do so.
It also allows over-riding of those parameters in special cases by the command line.
For those that don't want to take the chance that their parameters might be set up incorrectly, they can just use parameters.
Sometimes I'll even have more levels in the hierarchy, in order of precedence:
Value set while program running.
Command-line parameter.
Environment variable.
Local config file.
Global config file.
Default.
That way, for each variable, you just work your way up that list, setting it to the relevant value, if it's there.

I suggest you prefer command line parameters over environment vars unless
you need values that persist across commands.
you need system wide global values
Foredecker

Always prefer parameters when you can.
But say you have Script1 that calls Script2. Both scripts are distributed to many users. Script2 may need different parameters depending on the user, and the users don't want or are unable to alter Script1 for some reason. This is a case where environment variables might be useful.

Related

Is there a way in pentaho to put variable in the select value step?

Can I define inside a "select value step" a variable?
like ${column_name}
How can I make it work, I have a parameter that will change this column every time.
That step doesn't allow using variables to select the columns of the stream you want to keep.
In this case you could use Metadata Injection, read Pentaho documentation as well as study the example in the samples folder of your installation on how to use Metadata Injection.
You just need to check the box in the step select values

SSIS Using For Loop Container Not Executing Script Task and Data Flow Tasks

I'm reaching out to the experts as I have hit a wall with a recent project. I have created an SSIS package (2008R2) that uses a script task to build a SQL statement, where a variable(#month1) is being used within the SQL statement, to specify a month look back in a membership table. I want to also use the #month1 variable as a "counter" for the loop container to specify how many times to execute the query. The SQL query is attached to a data flow task to append these records into a table on a SQL server database. The script task and data flow task work outside of the for loop container with the initial value given for the #month1 variable but I cannot figure out how to make the for loop container update the #month1 "counter" variable so that the for each loop can use it as a "counter" and the SQL statement can use it as a condition with in the created SQL statement. Any one have any ideas or examples on how to do this?
** Update **
The For Loop container is the issue. The script task and data flow task work outside of the For Loop container. It will use the initial variable setting for #month1 and create the dynamic sql script, execute script and transfer data from source database server to the destination source server. The issue is when I place these steps within the For Loop container, the container executes and turns green but does not invoke the steps within it. This is why I'm thinking the container is not reading the variable #month1, even though the variable is set at the package level. Any thoughts?
First of all, try to set the data flow Delay Validation property to True. If it still not working, instead of passing the variable as parameter in the OLEDB Source use expressions:
Create a variable of type string.
Change its EvaluateAsExpression property to True
Set the expression similar to:
"select * from table
Where column =" + (dt_str, 50)#[User::month1]
In the OLEDB Source select the Access mode as SQL Command from variable and select this variable.
Be aware that the month1 variable is not created twice wuth different scopes, click on the data flow task and check the variable panel if it shows additional variables.
I appreciate everyone's responses but it seems I tricked myself on this one. In looking for the most complicated issue I overlooked the most simple and obvious one. The reason my For Loop was not executing the steps inside of the container was because I had the initial value for #month1 set to 3 (intentionally) and wanted to loop until it was resolved to -49. In the EvalExpression setting, it will evaluate until the statement is FALSE...so the evaluation I had in there of #month1 <= -49 was already false. It needed to be #month1 > -49 so as soon as it fell to -49 the statement would be false. I do this to myself more than I should admit, can't see the forest for the trees!

A fatal scripting error occurred. Variable is not defined

When I run this query in SQLCMD mode in SSMS 2017 and SQL Server DB. It works fine.
--SQLCMD mode
--DECLARE Global variables
:SETVAR daysBack -1
SELECT $(daysBack)
Result: -1
If I run only 1 line
SELECT $(daysBack)
in the same window on the same connection, or in another tab. I am getting error
fatal scripting error occurred.
Variable daysBack is not defined.
Why I am getting error?
and how can I make my varibale Global, for example like
SELECT '$(COMPUTERNAME)'
I don't think you can. SQLCMD variables are a client tool trick, they don't really exist as a SQL Server concept.
The connection and server are not aware of their existence and the system doesn't persist knowledge of variables used in previous batches when you submit a new batch.
From sqlcmd - Use with Scripting Variables:
If more than one type of variable has the same name, the variable with the highest precedence is used.
System level environmental variables
User level environmental variables
Command shell (SET X=Y) set at command prompt before starting sqlcmd
sqlcmd-v X=Y
:Setvar X Y
Of these, the first three are effectively taken from when a particular process was launched, unless that process has specific tooling to allow environmental variable to be edited. Neither SSMS nor SQLCMD has such functionality so you cannot create a variable in these categories once the tool is already running.
The fourth is SQLCMD specific and has no equivalent in SSMS. Only the last one (using :setvar) remains, and this does not create a "global" variable (which are in fact just the environmental variables and the SQLCMD built-in variables).

How to query Intersystems Caché to obtain database and license properties?

Question
Hi,
I'm trying to determine if I can query Intersystems Caché to obtain database properties and license properties. For the database, I'm mostly interested in properties like the current size, maximum size, block size, and the directory associated with the database. For the licenses, I'm total authorized, current available, minimum available, current active users, and maximum active users.
Background
I know that details about the database and licenses are available using the System Management Portal, but I'm trying to automate some actions that depend on these details.
I know that the %FREECNT utility is available to display space statistics for the database, but the only way I'll be able to use this utility to obtain the info I need is to write a script using AWK or SED (the system is on a Unix server) and I'd like to avoid that since I'm not as well-versed in Unix scripting as I'd like to be.
I know the ^DATABASE routine and the $SYSTEM.License.ShowCounts() function are available, but I will have to use AWK and SED for these too to eliminate the text returned that I don't need. In all cases, straight SQL will return a set of data that I can iterate over that will eliminate the extraneous text that's included by the routines/functions.
Additional Info
I've written queries similar to the one below and I'm hoping there are equivalent tables for database and license that will allow me the same access:
Select * From %SYS.ProcessQuery Where Namespace = 'HL7'
I don't have access to Caché Studio, so I'm forced to use the command line on the server. I know I can use the SQL.Shell to enter SQL statements and, from the documentation, it looks like I can create routines from the command line, but I haven't found any documentation that will allow me to enter multiline statements for routines from the command line. If that's not possible, then I probably can't use routines in my solution.
Thanks for the help.
In your Caché routine, you can use Query Summary for get some license information, or other queries in class %SYSTEM.License
For Databases you can use queries from SYS.Database from %SYS namespace
I was able to get something close.
From the command line, I entered the following:
%SYS>SET rs = ##Class(%Library.ResultSet).%New()
%SYS>SET rs.ClassName = "SYS.Database"
%SYS>SET rs.QueryName = "FreeSpace"
%SYS>SET sc = rs.Prepare(rs.QueryName)
%SYS>SET sc = rs.Execute($LISTBUILD("/my/database/directory"), 0)
%SYS>WHILE rs.Next(){WRITE rs.Data("DatabaseName")," "_rs.Data("Size")," "_rs.Data("MaxSize"),!}
It's not quite as clean as I would have hoped because I have to write the entire loop on a single line, but that's better than nothing. At least the statement wraps across lines.

Getting the SQL from a Doctrine Migration

I have been researching a way to get the SQL statements that are built by a generated Migration file. These extend Doctrine_Migration_Base. Essentially I would like to save the SQL as change scripts.
The execution path leads me to Doctrine_Export which has methods that build the SQL statement and executes them. I have found no way of asking for just them. The export methods found in Doctrine_Export only operate on Doctrine_Record models and not Migration scripts.
From the command line './doctrine migrate version#' the path goes:
Doctrine_Cli::run(cmd)
Doctrine_Task_Migrate::setArguments(args)
Doctrine_Task_Migrate::execute()
Doctrine_Migration::migrate(to)
Doctrine_Migration_Process::Doctrine_Export::various
create, drop, alter methods with sql
equivalents.
Has anyone tackled this before? I really would not like to change Doctrine base files. Any help is greatly appreciated.
Could you make a dev server, and do the migration on that, storing a SQL Trace as you go?you don't have to keep the results, but you would get a list of every command.
Taking into account Rob Farley's suggestion, I modified:
Doctrine_Core::migrate
Doctrine_Task_Migrate::execute
When the execute method is called the optional argument 'dryRun' is checked. If true
then a 'Doctrine_Connection_Profiler' instance is created. The 'dryRun' value is then passed onto
the 'Doctrine_Core::migrate' method. The 'dryRun' value of true allows the changes to rollback when done executing the SQL statements. When the method returns, the profiler is parsed and non-empty SQL statements
not containing 'migration_version' are saved and displayed to the terminal.