ADO Command saying that I am inserting NULL, when I'm not - c++

I'm using ADO to communicate with my Sybase server..
This is how I'm executing a simple command:
_ConnectionPtr m_ConnPtr;
//... Instantiate connection
_CommandPtr m_CommPtr;
m_CommPtr->CreateInstance(__uuidof(Command))
m_CommPtr->ActiveConnection = m_ConnPtr;
Variant m_variant;
m_variant.SetString("My Param Value");
_ParameterPtr ParamPtr;
ParamPtr = m_CommPtr->CreateParameter("#StrParam", (DataTypeEnum) m_variant.vt, adParamInput, NULL, m_variant);
m_CommPtr->Parameters->Append(PrmPtr);
m_CommPtr->CommandText = "EXECUTE my_stored_procedure #StrParam";
m_CommPtr->Execute(NULL, NULL, adOptionUnspecified);
#StrParam is supposed to be a VarChar type..
Running this gives me an error:
Attempt to insert NULL value into column 'StrParam'. table 'MYTABLE';
column does not allow nulls. Update fails.
I'm not sure why I'm getting this error, since I am specifiying its value ("My Param Value")..
Does anyone know what I'm doing wrong?
(I didn't include the Stored procedure,, because I'm sure there's nothing wrong with the procedure itself.. Other application using the same procedure works fine. So there must be something wrong with how I'm using the parametized command)

I have no clue what your Variant class even is. But the traditional variant type (vt) and the ADO data type are not synonymous. Second, you're not setting up the call nor parameters correctly for a typical stored-proc invoke.
Below is how you would do this using a standard stored proc call and variant_t from the comutil library:
_CommandPtr m_CommPtr(__uuidof(Command));
m_CommPtr->ActiveConnection = m_ConnPtr;
m_CommPtr->CommandType = adoCmdStoredProc;
m_CommPtr->CommandText = L"my_stored_procedure";
// setup parameter
variant_t vParam = L"My Param Value";
_ParameterPtr ParamPtr = m_CommPtr->CreateParameter(L"#StrParam", adBSTR, adParamInput, 0, vParam);
m_CommPtr->Parameters->Append(ParamPtr);
m_CommPtr->Execute(NULL, NULL, adOptionUnspecified);
Note that the ParamPtr is generally optional and you can straight-away append the parameter to the command's Parameters collection if you don't need it for anything else, like this:
m_CommPtr->Parameters->Append(m_CommPtr->CreateParameter(
L"#StrParam", adBSTR, adParamInput, 0, vParam));
The method you're using is common for parameters that are both input and output, as you retain the parameter object reference to extract the output side of the parameter. I see no evidence of that in your call, which is the only reason I mention it here.
Also note that unless the command returns rows for a result set you should also invoke with adExecuteNoRecords for the execution third option (which is typical for many fire-and-forget stored procedure executions)
Finally, the names of the parameters are not important unless you use the NamedParameters property of the command object. This is commonly done when you have additional parameters with default values that you would like to retain, setting only specific parameters as part of your append list.
Best of luck.

Related

How to create a Dataflow Template without running code?

I am creating a Dataflow template that runs perfectly if I pass all required parameters but my use case is to create a Generic Template where I can pass parameters at Runtime.
All my options are ValueProvider but still, it is trying to execute the code while creating the template and that gives an error. Is there any way I can create a Dataflow template without executing code?
I have also faced one weird issue when I use create template command along with all the parameters then it creates the template successfully but at that time all parameters get hard coded in the code and if I pass the new parameter value while running it does not change the value with the template.
Is it the correct behavior of the Dataflow template?
Command without passing all parameters :
mvn compile exec:java -D"exec.mainClass"="org.example.Main" -D"exec.args"="--runner=DataflowRunner --project=<project> --stagingLocation=gs://test-bucket/staging_4 --templateLocation=gs://test-bucket/templates/my_template --region=asia-south1 " -P dataflow-runner -X
After designing my code multiple times, I got to know what mistake I was doing.
What I got to know is that your code should be designed in such a way that it will not ask for any value for generating the Graph except Project Id, Stage Path, and Template Path. if it is asking then check the below practices and design accordingly.
Following are the practice you should follow if you are creating Custom Template.
1.Declare all the options as ValueProvider so that it will be calculated at Run Time and the Template creation process will skip it.
2.Do not assign the ValueProvider value to the normal variable as below.
String Query = options.getQuery().toString();
PCollection<TableRow> rows = p.apply("Read From Source", JdbcIO.<TableRow>read()
.withQuery(Query)
3.Try to pass ValueProvider value directly to the method. For example above code snippet should be like below
PCollection<TableRow> rows = p.apply("Read From Source", JdbcIO.<TableRow>read()
.withQuery(options.getQuery())
4.Do not use options only inside any one particular block of code which is never accessible during Template creation. As below example.
Boolean Check = false;
if (options.getA().isAccessible()){
Check = true;
}
if (Check == true){
//Use of Options.getB().
}
In the above case if you are not pass --a option while creating a template then the Check value will always false and a particular below block of code will not be executable. If we are not using --b out of Check block then after the creation of Template options b will be unknown to Template and it will give an error if you pass it at Run time.
5.If you have use case where you need to manipulate data of input options passed then you should use NestedValueProvider instead of converting ValueProvider into a Normal variable such as String and manipulate data.
Fo example, avoid the below practice.
String Query = String.format("SELECT * FROM %s", options.getTableName().toString());
PCollection<TableRow> rows = p.apply("Read From Source", JdbcIO.<TableRow>read()
.withQuery(Query)
Instead implement same logic as below:
ValueProvider<String> Query = NestedValueProvider.of(options.getTableName(),
new SerializableFunction<String, String>() {
#Override
public String apply(TranslatorInput<String, String> input)
{
return String.format("SELECT * FROM %s", input);;
}
});;
PCollection<TableRow> rows = p.apply("Read From Source", JdbcIO.<TableRow>read()
.withQuery(Query)
Use FlexTemplates instead. Documentation can be found here.

WMI calling method

I'm trying to change Intel network adapter settings using WMI. Accessing the classes works fine but according to the Intel documentation page 40 i need to call two methods in order to apply those changes.
So the IANet_NetService class should have the methods BeginApply and Apply. When I check this using PowerShell command get-wmiobject -namespace root\intelncs2 -class IAnet_NetService | get-member I can confirm that these methods are present.
The Intel documentation says I should enumerate the single instance in IANet_NetService.
So when I use CreateInstanceEnum method it will give me one result in the enumeration, but when I try to enumerate the methods for this instance, it won't find any.
Later I tried to use CreateClassEnum which had no results.
At last I tried a simple GetObject call to get the IANet_NetService item. With this item I was also able to enumerate the methods and find the BeginApply and Apply methods.
It is also possible to call GetMethod to receive the signature information. For the BeginApply method it has no input parameters which is correct according to the Intel docs. So I try to execute this method using pService->ExecMethod(L"IAnet_NetService", L"BeginApply", 0, 0, 0, &pOutInst, 0); which return WBEM_E_INVALID_METHOD_PARAMETERS. MSDN says this may be returned when the input parameters are wrong or I'm missing a [static] qualifier on the method.
The input parameters are correct, but I do not know what the missing [static] qualifier means in this case.
Anyone knows how to call this method?
The problem was, that i needed to use the GetObject/GetMethod combination to retrieve the input parameters and after this get the only instance of the object and ask for it's path. This path replaced L"IAnet_NetService" on the ExecMethod call and it's working.
WMI Method call without parameters:
This one is the exact code reference:
IEnumWbemClassObject * enum_obj;
hres = pSvc>CreateInstanceEnum(_bstr_t(L"IANet_NetService"),WBEM_FLAG_RETURN_IMMEDIATELY , NULL ,&enum_obj);
IWbemClassObject * spInstance;
ULONG uNumOfInstances = 0;
hres = enum_obj->Next(10000, 1,&spInstance,&uNumOfInstances);
VARIANT path;
hres = spInstance->Get(_bstr_t("__Path"), 0,&path, 0, 0);
IWbemClassObject *results = NULL;
hres = pSvc->ExecMethod( path.bstrVal, _bstr_t( L"Apply" ), 0,
NULL,NULL,&results, NULL );

Get query from sqlite3_stmt of SQLite in c/cpp [duplicate]

I'm using SQLite (3.6.4) from a C++ application (using the standard C api). My question is: once a query has been prepared, using sqlite3_prepare_v2(), and bound with parameters using sqlite3_bind_xyz() - is there any way to get a string containing the original SQL query?
The reason is when something goes wrong, I'd like to print the query (for debugging - this is an in-house developer only test app).
Example:
sqlite3_prepare_v2(db, "SELECT * FROM xyz WHERE something = ? AND somethingelse = ?", -1, &myQuery, NULL);
sqlite3_bind_text(myQuery, 1, mySomething);
sqlite3_bind_text(myQuery, 2, mySomethingElse);
// ....
// somewhere else, in another function perhaps
if (sqlite3_step(myQuery) != SQLITE_OK)
{
// Here i'd like to print the actual query that failed - but I
// only have the myQuery variable
exit(-1);
}
Bonus points if it could also print out the actual parameters that was bound. :)
You probably want to use sqlite3_trace
This will call a callback function (that you define) and on of the parameters is a char * of the SQL of the prepared statements (including bound parameters).
As per the comments in sqlite3.c (amalgamation), sqlite3_sql(myQuery) will return the original SQL text.
I don't see any function for finding the value bound at a particular index, but we can easily add one to the standard set of SQLite functions. It may look something like this:
const char* sqlite3_bound_value(sqlite3_stmt* pStmt, int index)
{
Vdbe *p = (Vdbe *)pStmt;
// check if &p->aVar[index - 1] points to a valid location.
return (char*)sqlite3ValueText(&p->aVar[index - 1], SQLITE_UTF8);
}
Well, the above code shows only a possible way sqlite3_bound_value() could be implemented. I haven't tested it, it might be wrong, but it gives certain hints on how/where to start.
Quoting the documentation:
In the "v2" interfaces, the prepared statement that is returned (the sqlite_stmt object) contains a copy of the original SQL text.
http://www.sqlite.org/c3ref/prepare.html

Unable to set user_version in SQLite

I am trying to use the user_version feature of an SQLite database. I am unable to actually set the user_version and I am not sure why. I have tried various ways of executing a query to update the user_version, and have searched extensively online and am now at a total loss.
Here is my query string.
const std::string kSetUserVersion = "PRAGMA user_version = 1;";
And here is where I am trying to set the user_version, however my result is still 0.
// Set the user version and check it is correct.
sqlite3_exec(dbConnection->db_handle, kSetUserVersion.c_str(), nullptr, nullptr, &db_err); // <-- this is not working!
long currentVersion = sqlite3_exec(dbConnection->db_handle, kGetUserVersion.c_str(), nullptr, nullptr, &db_err);
// If the PRAGMA statement fails, no error returns and it fails silently, so having to add check to see if it has worked.
if (currentVersion != 1) // Setting the user_version has failed.
{
throw DatabaseAccessException(sqlite3_errmsg(dbConnection->db_handle));
}
Any help is much appreciated.
sqlite3_exec() return value is a status/error code and not the value from your query.
To get the query result value, there are two primary options:
Use sqlite3_prepare_v2(), sqlite_step() for SQLITE_ROW and access the data with e.g. sqlite3_column_int(), finalizing the prepared query with sqlite3_finalize().
Supply a callback function as the third argument to your sqlite3_exec() to capture the value. See e.g. here for example: Proper use of callback function of sqlite3 in C++

Get original SQL query from prepared statement in SQLite

I'm using SQLite (3.6.4) from a C++ application (using the standard C api). My question is: once a query has been prepared, using sqlite3_prepare_v2(), and bound with parameters using sqlite3_bind_xyz() - is there any way to get a string containing the original SQL query?
The reason is when something goes wrong, I'd like to print the query (for debugging - this is an in-house developer only test app).
Example:
sqlite3_prepare_v2(db, "SELECT * FROM xyz WHERE something = ? AND somethingelse = ?", -1, &myQuery, NULL);
sqlite3_bind_text(myQuery, 1, mySomething);
sqlite3_bind_text(myQuery, 2, mySomethingElse);
// ....
// somewhere else, in another function perhaps
if (sqlite3_step(myQuery) != SQLITE_OK)
{
// Here i'd like to print the actual query that failed - but I
// only have the myQuery variable
exit(-1);
}
Bonus points if it could also print out the actual parameters that was bound. :)
You probably want to use sqlite3_trace
This will call a callback function (that you define) and on of the parameters is a char * of the SQL of the prepared statements (including bound parameters).
As per the comments in sqlite3.c (amalgamation), sqlite3_sql(myQuery) will return the original SQL text.
I don't see any function for finding the value bound at a particular index, but we can easily add one to the standard set of SQLite functions. It may look something like this:
const char* sqlite3_bound_value(sqlite3_stmt* pStmt, int index)
{
Vdbe *p = (Vdbe *)pStmt;
// check if &p->aVar[index - 1] points to a valid location.
return (char*)sqlite3ValueText(&p->aVar[index - 1], SQLITE_UTF8);
}
Well, the above code shows only a possible way sqlite3_bound_value() could be implemented. I haven't tested it, it might be wrong, but it gives certain hints on how/where to start.
Quoting the documentation:
In the "v2" interfaces, the prepared statement that is returned (the sqlite_stmt object) contains a copy of the original SQL text.
http://www.sqlite.org/c3ref/prepare.html