Invalid character value for cast specification sometimes - sql

Im currently investigating a bug that just happens sometimes. I have not been able to see any patterns to the behavior yet. I have a vb6 com+-application that communicates with the server.
Err: Invalid character value for cast specification. (&H80040E21)
Src: Microsoft OLE DB Provider for SQL Server
Stacktrace:
GetClientRS("SELECT * FROM Visit where GUID=?")
GetVisit("('{5EF4A26A-0909-4371-97F7-A2597CB7ADE3}')")
This is the error that happens sometimes. Maybe 1-2 times for every 5 times it is called. I have tried a trace in SQL server profiler but I am unable to detect any errors.
Does anyone have any ideas I could try?
Edit:
Code for calling the command:
GetVisit:
Set cmd = CreateCommand("SELECT * FROM dbo.per_Visit WHERE GUID=?")
cmd.Parameters.Append cmd.CreateParameter(, adGUID, , , SafeGUID(sGUID))
Set GetVisit = GetClientRS(cmd, True)
SafeGUID:
If Mid$(sGUID, 1, 1) <> "{" Then
sGUID = "{" & sGUID & "}"
End If
SafeGUID = sGUID

SafeGUID function is probably not clever enough.
When
sGUID = "('{5EF4A26A-0909-4371-97F7-A2597CB7ADE3}')"
the value actually passed as parameter is
{('{5EF4A26A-0909-4371-97F7-A2597CB7ADE3}')}
which is not a valid GUID.

Related

Excel power query, error handling for fallback connection/OleDb data source

I have a PowerQuery connected to DB2 Data Source, but because of some kind of load balancing the DB Server changes periodically (ip also changes), There is no way for me to know beforehand which data source (IP), I should use until I try it and see that it errors out, then I have to use the other one, I googled for error handling in PowerQuery and found some examples of error handling but this examples did not apply to my case, most of them handled errors AFTER the connection was made or were preventing errors on missing columns or files not found, I tried to adjust the examples to my case but was not able to.
What I want is just try one IP and if it fails then use the other one.
let
//fParametros("ParamQuery",1) is the "standard" Server/Ip address (provider=IBMDADB2.IBMDBCL1;data source=CP3;location=pn8us7ldbcp3.us.mycompany.com:5912)
dbSource = fParametros("ParamQuery",1),
//fParametros("ParamQuery",5) is the "Alternate" Server/Ip address (provider=IBMDADB2.IBMDBCL1;data source=CP3;location=pn8us7ldbcp3h.us.mycompany.com:5912)
AltdbSource = fParametros("ParamQuery",5),
pOrden = Text.From(fParametros("ParamQuery",2)),
//Create the query
dbQuery = "SELECT SAPCP3.vbak.VBELN SO , SAPCP3.vbap.posnr PoLine , SAPCP3.vbep.ETENR Sch_Line , SAPCP3.vbap.matnr Part_Number,SAPCP3.makt.maktx Description,SAPCP3.vbap.kwmeng Qty ,SAPCP3.vbep.BMENG Conf_qty ,SAPCP3.vbap.vrkme UOM ,SAPCP3.vbap.netpr SalesPrice ,SAPCP3.vbap.kpein LotSize FROM SAPCP3.vbak JOIN SAPCP3.vbap ON SAPCP3.VBAp.VBELN = SAPCP3.VBAK.VBELN JOIN SAPCP3.vbep ON SAPCP3.vbep.vbeln = SAPCP3.vbak.vbeln AND SAPCP3.vbap.posnr = SAPCP3.vbep.posnr JOIN sapcp3.makt ON sapcp3.vbap.matnr=sapcp3.makt.matnr WHERE SAPCP3.VBAK.VKORG = '4000' AND (SAPCP3.vbep.edatu >= '20190701') AND SAPCP3.vbak.VBELN ="& pOrden & " ORDER BY SAPCP3.vbak.VBELN",
//Get the data
Source = OleDb.DataSource(dbSource, [Query=dbQuery]),
//Failed Attempt to handle the error:
TestForError= try Source,
//next line does not work, I get error saying Source is already defined/declared
Source = if TestForError[HasError] then OleDb.DataSource(AltdbSource, [Query=dbQuery]) else OleDb.DataSource(dbSource, [Query=dbQuery])
in
Source
I also Tried the following:
.
.
.
//Get the data
Source = OleDb.DataSource(dbSource, [Query=dbQuery]),
//Failed Attempt to handle the error:
TestForError= try Source,
Output = if TestForError[HasError] then OleDb.DataSource(AltdbSource, [Query=dbQuery]) else OleDb.DataSource(dbSource, [Query=dbQuery])
in
Output
//This last part works if the dbSource is correct, but if it is not it doesnt catch the error and gives me the Connection error shown below:
DataSource.Error: OLE DB: SQL30081N A communication error has been detected. Communication protocol being used: "TCP/IP". Communication API being used: "SOCKETS". Location where the error was detected: "172.16.0.1". Communication function detecting the error: "connect". Protocol specific error code(s): "10061", "", "". SQLSTATE=08001
Details:
DataSourceKind=OleDb
DataSourcePath=data source=CP3;location=pn8us7ldbcp3.us.mycompany.com:5912;provider=IBMDADB2.IBMDBCL1
Message= SQL30081N A communication error has been detected. Communication protocol being used: "TCP/IP". Communication API being used: "SOCKETS". Location where the error was detected: "172.16.0.1". Communication function detecting the error: "connect". Protocol specific error code(s): "10061", "", "". SQLSTATE=08001
ErrorCode=-2147467259
I want to connect to dbSource (172.16.0.1) and if it is not possible then connect to AltdbSource (172.16.0.2)
Currently I have 2 identical excel sheeets and user needs to open one or the other if he gets the connection error, I want it to change automatically.
I'm guessing that TestForError = try OleDb.DataSource(BadSource) isn't working because OleDb.DataSource(...) returns a table value than only produces an error when trying to enumerate rows.
What if you change TestForError to drill into the first row if it exists:
TestForError= try Source{0}?,
If that still doesn't work, next try indexing into a table cell in the first row.

Oracle 9i ignores query alias sent from vb.net

The following code is from a released version of an application using framework version 1 and Oracle 9i.
strSQL = "SELECT COURSE_CODE AS CODE FROM COURSE_REVISIONS WHERE DOC_REF_CODE = '" & doc_ref_prevcode & "'"
objDataset = stkDataAssistant.getTable(strSQL)
course_code = objDataset.Tables(0).Rows(0)("Course_Code").ToString
Response.Redirect("../Courses/CourseRevisionNew.aspx?flag=add&course_code=" & course_code)
It is throwing an error on the following line:
course_code = objDataset.Tables(0).Rows(0)("Course_Code").ToString
It is known that there is an error in the sql string with the alias CODE. This issue was being ignored in the clients environment and was working until a month ago that is now throwing an error in the stated line above.
Is this error showing up now because of some sort of framework change? Or is it with Oracle?
The client states that there has been updates to the server where the database resides but the application was still working as expected. The error started showing up 3 months later and there has no changes done to either the database or application environment.
Oracle 9i has been out of support for many, many years. However you have to work with what you have, try this:
SELECT "COURSE_REVISIONS"."COURSE_CODE"
FROM "COURSE_REVISIONS"
WHERE "COURSE_REVISIONS"."DOC_REF_CODE" = 'QDMSPROD';
Or you could make a view with the alias that you want and select from that.

VB->Option strict and LINQ result

I was recently introduced to LINQ and got a sample how to search for error messages after executing a query against a database. The code looks like this:
Dim errors As Object = From e In execution.Messages _
Where e.MessageType = 120 Or e.MessageType = 110
Select e.Message
If errors IsNot Nothing Then
For Each m As OperationMessage In errors
LogToError("ExecutePackage->Error message: " & m.Message)
sbError.AppendLine(m.Message)
Next
End If
Now, when I use Option strict ON I get an error on the "errors" object on this line:
For Each m As OperationMessage In errors
This is natural for me. So, I tried to change the code to this:
For Each m As OperationMessage In CType(errors, OperationMessageCollection)
Now, when I run it I get this error:
Unable to cast object of type 'WhereSelectEnumerableIterator`2[Microsoft.SqlServer.Management.IntegrationServices.OperationMessage,System.String]' to type 'Microsoft.SqlServer.Management.IntegrationServices.OperationMessageCollection'.
So, it seems to me that converting a LINQ query to another type at runtime does not work? What is the proper way of doing this and keeping Option strict ON?

select count(*) not working with perl DBI

The goal of my code is to return a count of the number of rows in a table based on one specific parameter.
Here is code that works:
######### SQL Commands
### Connect to the SQL Database
my $dbh = DBI->connect($data_source, $user, $pass)
or die "Can't connect to $data_source: $DBI::errstr";
### Prepare the SQL statement and execute
my $sth1 = $dbh->selectrow_array("select count(*) from TableInfo where Type = '2'")
or die "Can't connect to $data_source: $DBI::errstr";
### Disconnect from Database statements are completed.
$dbh->disconnect;
######### end SQL Commands
print $sth1;
This will successfully print a number which is 189 in this instance.
When I try to use the same code but change the "Type = '2'" (which should return a value of 2000) I get the following error:
DBD::ODBC::db selectrow_array failed: [Microsoft][ODBC Driver 11 for SQL Server]Numeric value out of range (SQL-22003) at ./getTotalExpSRP.cgi line 33, <DATA> line 225.
Can't connect to dbi:ODBC:BLTSS_SRP: [Microsoft][ODBC Driver 11 for SQL Server]Numeric value out of range (SQL-22003) at ./getTotalExpSRP.cgi line 33, <DATA> line 225.
I've search everywhere but I cannot find out why this happens.
From the symptom of the issue I would guess that there is a limit to the size of the results returned but I cannot find any supporting evidence of this.
I have run a trace on my Microsoft SQL 2005 server and can confirm that the sql statement is being run properly with no errors.
I've viewed my odbc trace log but unfortunately I cannot derive any useful information when comparing a working example to the failed one.
Any help would be appreciated!!
Thanks,
Now we've seen the trace I can explain this. DBD::ODBC calls SQLDescribeCol and is told:
DescribeCol column = 1, name = , namelen = 0, type = unknown(0), precision/column size = 10, scale = 0, nullable = 1
display size = 11
Then it calls SQLColAttribute and is told the column size is 4. Since the column type was unknown (why the driver did that I'm not sure) DBD::ODBC decides to bind the column as a char(4) and so as soon as the count is > 3 digits it will overflow.
The version of DBI and DBD::ODBC being used here is really old and I suspect the latest versions will cope better with this.
Numeric value out of range is a type conversion error. Is TYPE supposed to be a number of a character/string? If it should be a number, use a number
my $sth1 = $dbh->selectrow_array(
"select count(*) from TableInfo where Type=2") # Type=2, not Type='2'
or use placeholders and let Perl and the database driver worry about type conversions
my $sth = $dbh->prepare("select count(*) from TableInfo where Type=?");
$sth->execute(2);
$sth->execute('2'); # same thing
my $st1 = $sth->fetchall_arrayref;

Paramaterising SQL in SSIS

I'm trying to paramaterize some queries in SSIS. After some reading, it sounds like my best option is to create one variable that contains my base sql, another that contains my criteria and a final variable that is evaluated as an expression that includes both of these. I want to end up with an SQL query that is effectively
UPDATE mytable set something='bar' where something_else='foo'
So my first two variables have the scope of my package and are as follows:
Name: BaseSQL
Data Type: String
Value: UPDATE mytable set something = 'bar' where something_else =
Name: MyVariable
Data Type: String
Value: foo
My third variable has a scope of the data flow task where I want to use this SQL and is as follows:
Name: SQLQuery
Data Type: String
Value: #[User::BaseSQL] + "'" + #[User::MyVariable] + "'"
EvaluateAsExpression: True
In the OLE DB Source, I then choose my connection and 'SQL command from variable' and select User::SQLQuery from the dropdown box. The Variable Value window then displays the following:
#[User::BaseSQL] + "'" + #[User::MyVariable] + "'"
This is as desired, and would provide the output I want from my DB.
The variable name dropdown also contains User::BaseSQL and User::MyVariable so I believe that my namespaces are correct.
However, when I then click preview, I get the following error when configuring an OLE DB Source (using SQL command from variable):
TITLE: Microsoft Visual Studio
Error at Set runtime in DB [Set runtime in myDb DB [1]]: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80040E14.
An OLE DB record is available. Source: "Microsoft SQL Server Native Client 10.0" Hresult: 0x80040E14 Description: "Statement(s) could not be prepared.".
An OLE DB record is available. Source: "Microsoft SQL Server Native Client 10.0" Hresult: 0x80040E14 Description: "Must declare the scalar variable "#".".
(Microsoft Visual Studio)
Can anyone advise what I'm missing or how I can resolve this please ?
Thanks in advance!
I had a similar issue.
It seems to be that the designer wants something at design time.
I was getting the error when i tried to click OK on the oleDBSource task after choosing a variable name.
I had a similar situation where the where clause logic was a bit involved and required a script task to assign its value.
This is what things looked like at design time.
#basesql = "select from mytable where "
#where = empty string
#fullsql = #basesql + #where
i was getting the E14 error you mentioned above.
by changing the design time value of #where to something silly, the oleDBSource task got what it wanted and let me use the variable.
#where = " value1 is null and value2 = 'easteregg' "
Related issue, to even get the thing to work, i had to start out by putting a basic select stmt into the sql command so it could go get source columns.
It makes sense, but that step took me and google a while to figure out.
You should set the Expression property of SQLQuery, instead of the Value property. If you do it correctly, the Variable Value window should show you the result of the expression:
UPDATE mytable set something = 'bar' where something_else = 'foo'
I would create a script task and concatenate the strings into one variable and use that as your source:
Dts.Variables["SQLQuery"].Value = Dts.Variables["BaseSQL"].Value.ToString() +
Dts.Variables["MyVariable"].Value.ToString();
Then, in the advanced properties under the component properties tab, you need to change the ValidateExternalMetadad property to False so SSIS will not try to prevalidate your sql query in your variable which would give you a run time error. Just created a simple package and that seemed to work. Hope this helps.
-Ryan