VB.NET Database reading error - database

I have this SQL sentence for retrieving a specific role (by the column RoleID) from the table Roles:
DBBroker.getInstance.read("SELECT * FROM Roles WHERE RoleID='" & role.roleID & "';")
The thing is that when my program runs the sentence, I obtain this error:
I work with a Microsoft Access Database in which RoleID is defined as Autonumber while in my program it is defined as String. Anyway I tried changing Types but it still fails.
I have too much code in the program so I cannot include it here, but I'm open for any requests regarding a specific part of the program.
Thanks
By the way I worked before on another similar database and the exact same clause did work indeed.

Though you solved your problem,i am answering this just to describe and help guys who visit this page in future
Here's a one line explanation of the issue :
The data type you set for the column in the table of the database is different than the type of value you are passing
For example : In simple words, you have a word and a number , can you add them ? I mean in a mathematical way ? The answer is NO.
Now assuming that your data-type for the RoleID column is Integer but role.RoleId is of type/returns value of type String , then there will be a data-type mismatch as one is an integer and the other is a String.
Now, going through the comments , i see that you've solved your issue.Now, let me explain how you solved it.
Your sql query looks like this :
"SELECT * FROM Roles WHERE RoleID='" & role.roleID & "';"
Let's point out the main relevant part :
RoleID='" & role.roleID & "'
Here,before you close the string RoleID= with double quotes, you use '(single quote).In sql-queries, single quotes are used to declare/give a value(of type STRING) to the required/given parameter(of the query).
In order to pass an Integer value ,you can pass it without the ' single quote like this :
RoleID=12345
So, the answer is simple:You were passing some data of type String to a column which expects data/even if the passed value is of type intger but because you were using ' single quotes when passing the values,the quote had converted it to a String ..So, all u have to do(had to do-in your case) is remove the two single quotes(')
Hope this helps to enrich your knowledge :)

Related

SSRS How to see multi value parameter in subscription

I tried to get value from query or to specify values, as soon as the parameter is multi value i can't see the data when i'm trying to make my subscription.
my request looks like :
select id from employee where canal in(#canal)
what should i do, i'm totally stuck,
when i did research i saw data driven subscription but i don't have access to it apparently, don't know if that help
I'll start by saying sorry this isn't a pleasant answer. You've run into a limitation with the built-in functionality. Thankfully there are workarounds.
The problem is that you can only pass 1 value into the data-driven subscription. So you have use a comma-separated list and get the query/report to parse out the values.
If you have or can create a Split function in your database, that is a good option. This would be a table-valued user defined function and there are some easy to find examples already. Also this function is generally good to have for other use cases anyway. With this your SQL would read:
where canal in Split(#canal)
SSRS works really well with SQL Server, but when you use an ODBC connection, the parameter support is limited. You can use the same multi-value parameter workaround that is required in those cases.
In the Dataset properties > parameters tab, use an expression like this to combine the values into a single comma-separated string surrounded by commas.
="," + Join(Parameters!canal.Value, ",") + ","
The SQL would look like this:
where # like '%,' + canal + ',%'
Basically, this searches row-by-row for values that are contained in the string.
In either case, the query in your data-driven subscription settings will need to return the comma-separated string. Then you can select that column in the report parameters value field. Hope this helps!

SSIS Derived Column - Text in Numeric Field is not converting

I'm importing thousands of csv files into an SQL DB. They each have two columns: Date and Value. In some of the files, the value column contains simply a period (ex: "."). I've tried to create a derived column that will handle any cell that contains a period with the following code:
FINDSTRING((DT_WSTR,1)[VALUE],".",1) != 0 ? NULL(DT_R8) : [VALUE]
But, when the package runs it gets the following error when it reaches the cell with the period in it:
The data conversion for column "VALUE" returned status value 2 and status text
"The value could not be converted because of a potential loss of data".
I'm guessing there might be an escape character that I'm missing in my FINDSTRING function but I can't seem to find what that may be. Does anyone have any thoughts on how I can get around this issue?
Trying to debug things like this is why I always advocate adding many Derived Columns to the Data Flow. It's impossible to debug that entire expression. Instead, first find the position of the period and add that as a new column. Then you can feed that into the ternary operation and bit by bit you can add data viewers to ensure you are seeing what you expect to see.
Personally, I'd take a different approach. It seems that you'd like to make any columns that are . into a null of type DT_R8.
Add a derived column, TrimmedValue and use this expression to remove any leading/trailing whitespace and then
RTRIM(LTRIM(Value))
Add a second derived column component, this time we'll add column MenopausalValue as it will remove the period. Use this expression
(TrimmmedValue == ".") ? Trimmedvalue : NULL(DT_WSTR, 50)
Now, you can add your final Derived Column wherein we convert the string representation of Value to the floating point representation.
IsNull(MenopausalValue) ? NULL(DT_R8) : (DT_R8) MenopausalValue
If the above shows an error, then you need to apply the following version as I can never remember the evaluation sequence for ternary operations that change type.
(DT_R8) (IsNull(MenopausalValue) ? NULL(DT_R8) : (DT_R8) MenopausalValue)
Examples of breaking these operations into many steps for debugging purposes
https://stackoverflow.com/a/15176398/181965
https://stackoverflow.com/a/31123797/181965
https://stackoverflow.com/a/33023858/181965
You can do it like this:
TRIM(Value) == "." ? NULL(DT_R8) : (DT_R8)Value

Database access excel formatting or if statement or grouping

I have a database formatting problem in which I am trying to concatenate column "B" rows based on column "A" rows. Like So:
https://docs.google.com/spreadsheet/ccc?key=0Am8J-Fv99YModE5Va3hLSFdnU0RibmQwNVFNelJCWHc
Sorry I couldn't post a picture. I don't have enough reputation points YET. I'LL Get them eventually though
So I'd like to solve this problem within Excel or Access. Its currently an access database, but I can export it to excel easily. As you can see, I want to find "userid" in column A and where there are multiple column A's such as "shawn" I'd like to combine the multiple instances of shawn and concatenate property num as such.
Even though there are multiple instances of column A still, I could just filter all unique instances of the table later. My concern is how to concatenate column B with a "|" in the middle if column A has multiple instances.
This is just a segment of my data (There is a lot more), so I would be very thankful for your help.
The pseudo code in my head so far is:
If( Column A has more than one instance)
Then Concatenate(Column B with "#"+ "|" +"#")
I'm also wondering if there is a way to do this on access with grouping.
Well Anyways, PLEASE HELP.
In excel we can achieve it easily by custom function in vba module. Hopefully using vba(Macros) is not an issue for you.
Here is the code for the function which can be added in vba. (Press Alt+F11, this will take you to visual editor, right click the project and add a module. Add the below code in module)
Public Function ConcatenatePipe(ByVal lst As Range, ByVal values As Range, ByVal name As Range) As String
ConcatenatePipe = ""
Dim i As Integer
For i = 1 To lst.Count
If name.Value = lst.Item(i).Value Then ConcatenatePipe = ConcatenatePipe & "|" & values.Item(i).Value
Next
ConcatenatePipe = Mid(ConcatenatePipe, 2)
End Function
This function you can use in excel in F Column of your example. Copy the below formulla in F2 and the copy paste the cell to rest of F column. =ConcatenatePipe($A$2:$A$20,$B$2:$B$20,E2)
I believe you can solve this with an SQL GROUP BY function. At least, here's how I'd do it in MySQL or similar:
SELECT userid, GROUP_CONCAT(propertynum SEPARATOR '|') FROM Names GROUP BY userid
as described in this stack overflow post: How to use GROUP BY to concatenate strings in MySQL?
Here's a link on how to use SQL in MS Access: http://www.igetit.net/newsletters/Y03_10/SQLInAccess.aspx
Unfortunately there is not a GROUP_CONCAT function in MSAccess, but this other SO post explains some ways round that: is there a group_concat function in ms-access?

Inserting an array column into the db in Yii

I needed to insert an array field into a database and I was pleased to notice that PostGreSQL had that functionality. But now I am not able to insert the data using the tables active record.
I have tried the below calls with no success
$active_record->array_column = $_array_of_values;
which gives me the exception
Exception Raised:CDbCommand failed to execute the SQL statement: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: array value must start with "{" or dimension information
I have also tried this using
foreach($_array_of_values as $value){
$active_record->array_column[] = $value;
}
which tells me
Indirect modification of overloaded property FeatureRaw::$colors_names has no effect
Can anyone help me with this?
Thanks!
Data must be inserted in the form (text representation of an ARRAY):
INSERT INTO tbl (arr_col) VALUES ('{23,45}')
Or:
INSERT INTO tbl (arr_col) VALUES ('{foo,"bar, with comma"}')
So you need to enclose your array values in '{}' and separate them with comma ,. Use double quotes "" around text values that include a comma.
I listed more syntax variants to insert arrays in a related answer.
For those who also have same problem:
I didn't check the Yii1 behavior, but in Yii2 you simply can insert array as properly formed string as Erwin Brandstetter mentioned in his comment:
$activeRecord->arrayField = '{' . implode(',',$array_values) . '}';
Of course you need to make additional efforts when your $array_values has strings with commas, etc. And you still need to convert value back to array after you load ActiveRecord.
You can make these conversions in ActiveRecord's beforeSave() and afterLoad() and you will not need to convert values manually.
UPD. Recently I made a simple behavior for Yii2 to use array fields with ActiveRecord without manual field building: kossmoss/yii2-postgresql-array-field. It is more generalized way to solve the problem and I hope it will help. For those who use Yii1: you can investigate the package code and create your own solutuion compatible with your framework.

Real examples of SQL injection issues for SQL Server using only a Replace as prevention?

I know that dynamic SQL queries are bad due to the SQL Injection issues (as well as performance and other issues). I also know that parameterized queries are prefered to avoid injection issues, we all know that.
But my client is still very stubborn and thinks that just
var UserName=Request.Form["UserName"];
UserName=UserName.Replace("'","''");
SQL="SELECT * FROM Users where UserName='" + UserName + "'";
Is enought protection against SQL injection issues against (SQL Server (Only), not mysql).
Can anyone give me real SQL Injection attack example that still can get through the Replace case above? Guess there's some unicode character issues?
I want some real live examples of attacks that still can get through that simple replace.
My question is only for SQL Server and I know that MySQL has some issues with the \ character.
This will not work if you are using NUMBERs.
"SELECT * FROM data WHERE id = " + a_variable + ";"
using
1;DROP TABLE users
Gives you
SELECT * FROM DATA WHERE id=1;DROP TABLE users;
Have a look at
SQL injection
MSDN SQL Injection
EDIT
Have a look at this. It is very close to your question
Proving SQL Injection
Please input your age : 21; drop table users;
SELECT * FROM table where age = 21; drop table users;
ouchies
I have some trouble understanding the scope of replacement. Your original line is:
SQL=SQL.Replace("''","'");
Because you apply it to the variable name SQL, I would assume you are replacing all occurrences of '' with ' in the entire statement.
This can't be correct: consider this statement:
SELECT * FROM tab WHERE col = '<input value goes here>'
Now, if is the empty string, the statement will be:
SELECT * FROM tab WHERE col = ''
...and after SQL.Replace("''", "'") it will become:
SELECT * FROM tab WHERE col = '
As you can see, it will leave a dangling single quote, and yields a syntax error.
Now, let's suppose you intended to write SQL.Replace("'", "''") then the replaced statement would become:
SELECT * FROM tab WHERE col = ''''
Although syntactically correct, you are now comparing col to a literal single quote (as the '' inside the outer single quotes that delimit the literal string will evaluate to a literal single quote). So this can't be right either.
This leads me to believe that you might be doing something like this:
SQL = "SELECT * FROM tab WHERE col = '" & ParamValue.Replace("'", "''") & "'"
Now, as was already pointed out by the previous poster, this approach does not work for number. Or actually, this approach is only applicable in case you want to process the input inside a string literal in the SQL stament.
There is at least on case where this may be problematic. If MS SQL servers QUOTED_IDENTIFIER setting is disabled, then literal strings may also be enclosed by double quote characters. In this case, user values injecting a double quote will lead to the same problems as you have with single quote strings. In addition, the standard escape sequence for a single quote (two single quotes) doesn't work anymore!!
Just consider this snippet:
SET QUOTED_IDENTIFIER OFF
SELECT " "" '' "
This gives the result:
" ''
So at least, the escaping process must be different depending on whether you delimit strings with single or with double quotes. This may not seem a big problem as QUOTED_IDENTIFIER is ON by default, but still. See:
http://msdn.microsoft.com/en-us/library/ms174393.aspx
Please see this XKCD cartoon:
Little Bobby Tables
The answers so far have been targeting on condition query with numeric datatypes and not having single quote in the WHERE clause.
However in MSSQL *at least in ver 2005), this works even if id is say an integer type:
"SELECT * FROM data WHERE id = '" + a_variable + "';"
I hate to say this but unless stored procedure (code that calls EXECUTE, EXEC, or sp_executesql) is used or WHERE clauses do not use quotes for numeric types, using single quote replacement will almost prevent possibility of SQL Injection. I cannot be 100% certain, and I really hope someone can prove me wrong.
I mentioned stored procedure due to second level injection which I only recently read about. See an SO post here on What is second level SQL Injection.
To quote from the accepted answer of the SO question "Proving SQL Injection":
[...] there is nothing inherently unsafe in a properly-quoted SQL statement.
So, if
String data is properly escaped using Replace("'","''") (and your SQL uses single quotes around strings, see Roland's answer w.r.t. QUOTED_IDENTIFIER),
numeric data comes from numeric variables and is properly (i.e. culture-invariantly) converted to string, and
datetime data comes from datetime variables and is properly converted to string (i.e. into one of the culture-invariant formats accepted by SQL Server).
then I cannot think of any way that SQL injection could be done in SQL Server.
The Unicode thing you mentioned in your question was a MySQL bug. Accounting for such problems in your code provides an extra layer of security (which is usually a good thing). Primarily, it's the task of the database engine to make sure that a properly-quoted SQL statement is not a security risk.
Your client is correct.
SQL = SQL.Replace("'","''");
will stop all injection attacks.
The reason this is not considered safe is that it's easy to miss one string entirely.

Resources