VB.NET, SQL Server and list of dates - sql-server

I have a query that takes as a parameter a list of dates. In VB.NET the dates are in a string ArrayList and I am using the String.Join() method to get them in a comma delimited list. The problem is when I do that double quotes are put at the start and end of the string and SQL complains about that (I think; see below). How can I get a list of date from a string ArrayList without the quote.
My arraylist contains these values:
'2020-08-30'
'2020-08-27'
'2020-09-28'
'2020-09-09'
'2020-08-31'
'2020-08-29'
when I join them using String.Join(",", sDates) I get the following:
"'2020-08-30','2020-08-27','2020-09-28','2020-09-09','2020-08-31','2020-08-29'"
and when I use that in a parameter query it gets rejected.
comm.Parameters.AddWithValue("#dates", String.Join(",", sDates))
sql contains the following"
...where pj.ProjectName =#projectname And tcd.Date in (#dates)
Exact error I get is
System.Data.SqlClient.SqlException
HResult=0x80131904
Message=Incorrect syntax near ','.
Source=.Net SqlClient Data Provider
Any advice?

This error message:
Incorrect syntax near ','
Is not caused by the way you've done your IN. It is caused by something else, such as a misplaced comma in a select block:
SELECT , a FROM x
^
The way you've done your IN won't work either, because it's conceptually the same as writing this:
SELECT * FROM table WHERE dateColumn IN ('''2000-01-01'',''2000-02-01''')
There is no such date with a string value of '2000-01-01','2000-02-01'.
If you want to use IN in the style you're attempting here, you have to add a parameter per date value and set it up accordingly:
sqlCommand.CommandText = "SELECT * FROM table WHERE dateCol IN("
Dim p = 0
For Each d as DateTime in MyDateList
sqlCommand.CommandText &= "#p" & i & "," 'concat param placeholder on
sqlCommand.Parameters.AddWithValue("#p" & i, d)
i += 1
Next d
sqlCommand.CommandText = sqlCommand.CommandText.TrimEnd(","c) & ")" 'get rid of trailing comma and close the IN brackets
This will generate an sql like
SELECT * FROM table WHERE dateCol IN (#p0,#p1,#p2)
with 3 parameters, and a populated parameters collection. You've already been pointed to Joel's blog about AddWithValue, so I won't repeat it.. But i did want to say that the way you've presented your question implies you have a list of strings, not datetimes. You should definitely make sure your list has DateTimes in, and your db column should be a date based type, not a string based type

Related

"Error 2147217904 No value given for one or more required parameters" When trying to fetch data using "WHERE" where clause in Excel

I am trying to fetch data from Excel (as Database) when I put simple select query "select * from [Sheet1$]" its working fine and retrieve the data from sheet1. but when I put the conditional statement (where or Like) its throws the error "Error 2147217904 No value given for one or more required parameters".
Query Which is throw error ---
"select * from [Sheet1$] WHERE [Sheet1$].[ColName]= User"
OR
"select * from [Sheet1$] WHERE [ColName] = " & ColName_RunTime
OR
"SELECT * FROM [Sheet1$A2:E2] WHERE ColName =Yes"
Thanks in advance for help or solution.
The error is 0x80040E10L DB_E_PARAMNOTOPTIONAL No value given for one or more required parameters. See: https://technet.microsoft.com/en-us/library/ms171852(v=sql.110).aspx
Effectively, as you point out, there's something wrong with how you are supplying the values for your WHERE clause. It appears that you want to supply a string, so, they must be enclosed in single quotes.
"select * from [Sheet1$] WHERE [Sheet1$].[ColName]= 'User' "

Working with the data from LinQ SQL query

Using VS 2013 (VB) and SQL server 2016.
I have linQ query that returns two columns from a database. The query is as follows.
Dim val = (From value In db.ngc_flowTypes
Where value.defaultValue IsNot Nothing
Select value.flowName, value.defaultValue)
The data it returns is a as follows.
I want to iterate through each row of the results and pass the values to certain variables. A ForEach statement doesnt seem to work as it just runs through once. I am sure this must be easy but I ont quite understand it. Am I getting the data returned in the best way via my query? Can I transpose the data to a data table in VB? so I can work with it easier?
The end result I want is string for each flow name with its corresponding default value (along with some other text). So something like this.
dim strsubmission as string = flowName + " has a value of " + defaultValue
Use ToDictionary.
Dim val = (From value In db.ngc_flowTypes
Where value.defaultValue IsNot Nothing
Select value).ToDictionary(Function(key) key.flowName,
Function(value) value.defaultValue)
This will actually execute the SQL of the linq on the database (approx. Select * From ngc_flowTypes Where defaultValue Is Not NULL), traverse each record into a key/value pair (flowName, defaultValue) and put it into a in-memory dictionary variable (val).
After that you can do whatever you like with the dictionary.
For Each flowName In val.Keys
Console.WriteLine("{0} has a value of {1}", flowName, val(flowName))
Next
Edit:
This will only work as long flowName is unique in table ngc_flowTypes

Error in VB.Net -- Conversion failed when converting from a character string to uniqueidentifier

I get a "Conversion failed when converting from a character string to uniqueidentifier."
I am using a String on the VB side and a GUID on the database side.....
Is there an equivalent field that I can use on the VB side that can work well with a "uniqueidentifier" data type in the Sql Server
If you already have your value as a string and since you are writing out your SQL by hand, you can CONVERT it like this:
strSql.Append("INSERT INTO tableName ")
strSql.Append("(GUID, ParentObsSetGUID, ChildObsSetGUID, ChildObsItemGUID) ")
strSql.Append(String.Format("VALUES (CONVERT(uniqueidentifier, '{0}'), CONVERT(uniqueidentifier, '{1}'), CONVERT(uniqueidentifier, '{2}'), CONVERT(uniqueidentifier, '{3}'))", parmList.ToArray))
EDIT: If you have an empty string and you need a new Guid, then do this:
parmList.Add(Guid.NewGuid().ToString())
instead of
parmList.Add(String.Empty)
If you would rather insert a NULL into the GUID column, then you need to change the last bit of your code to be like this instead:
parmList.Add(dtNewGUID.Rows(0).Item(0).ToString)
parmList.Add(dtResultParentGUID.Rows(0).Item(0).ToString)
parmList.Add(dtResultChildGUID.Rows(0).Item(0).ToString)
// remove the line with the empty string parameter
strSql.Append("INSERT INTO tableName ")
strSql.Append("(GUID, ParentObsSetGUID, ChildObsSetGUID, ChildObsItemGUID) ")
strSql.Append(String.Format("VALUES (CONVERT(uniqueidentifier, '{0}'), CONVERT(uniqueidentifier, '{1}'),
CONVERT(uniqueidentifier, '{2}'), NULL)", parmList.ToArray))
// Note the change to the last line. '{3}' becomes NULL.
// Make sure you remove the single quotes
NOTE: Your code as it stands (and this answer) is/are vulnerable to a SQL Injection attack, but that's another matter. At least with this answer you know how to convert the string to a uniqueidentifier.

Building dynamic query for Sql Server 2008 when table name contains " ' "

I need to fetch Table's TOP_PK, IDENT_CURRENT, IDENT_INCR, IDENT_SEED for which i am building dynamic query as below:
sGetSchemaCommand = String.Format("SELECT (SELECT TOP 1 [{0}] FROM [{1}]) AS TOP_PK, IDENT_CURRENT('[{1}]') AS CURRENT_IDENT, IDENT_INCR('[{1}]') AS IDENT_ICREMENT, IDENT_SEED('[{1}]') AS IDENT_SEED", pPrimaryKey, pTableName)
Here pPrimaryKey is name of Table's primary key column and pTableName is name of Table.
Now, i am facing problem when Table_Name contains " ' " character.(For Ex. KIN'1)
When i am using above logic and building query it would be as below:
SELECT (SELECT TOP 1 [ID] FROM [KIL'1]) AS TOP_PK, IDENT_CURRENT('[KIL'1]') AS CURRENT_IDENT, IDENT_INCR('[KIL'1]') AS IDENT_ICREMENT, IDENT_SEED('[KIL'1]') AS IDENT_SEED
Here, by executing above query i am getting error as below:
Incorrect syntax near '1'.
Unclosed quotation mark after the character string ') AS IDENT_SEED'.
So, can anyone please show me the best way to solve this problem?
Escape a single quote by doubling it: KIL'1 becomes KIL''1.
If a string already has adjacent single quotes, two becomes four, or four becomes eight... it can get a little hard to read, but it works :)
Using string methods from .NET, your statement could be:
sGetSchemaCommand = String.Format("SELECT (SELECT TOP 1 [{0}] FROM [{1}]) AS TOP_PK, IDENT_CURRENT('[{2}]') AS CURRENT_IDENT, IDENT_INCR('[{2}]') AS IDENT_ICREMENT, IDENT_SEED('[{2}]') AS IDENT_SEED", pPrimaryKey, pTableName, pTableName.Replace("'","''"))
EDIT:
Note that the string replace is now only on a new, third substitution string. (I've taken out the string replace for pPrimaryKey, and for the first occurrence of pTableName.) So now, single quotes are only doubled, when they will be within other single quotes.
You need to replace every single quote into two single quotes http://beyondrelational.com/modules/2/blogs/70/posts/10827/understanding-single-quotes.aspx

INSERT variable values into a table

I have several variables in an SSIS package that I would like inserting into a table.
example:-
#financialMonth, #Status, #Comments
The Variables have been populated along the way with values based on lookups, filename, dates, etc, and I want to store them in a results table.
Is using the execute SQL task the way to do this ?
Do I need to call a sproc and pass those variales as parameters ?
I've tried putting the following T-SQL into the SQLStatement property
INSERT INTO FilesProcessed
(ProcessedOn, ProviderCode, FinancialMonth,
FileName, Status, Comments)
SELECT GETDATE(), 'ABC' , 201006,
'ABC_201005_Testology.csv',
'Imported','Success'
I tried hardcoding the values above to get it to work
These are the columns on the table I'm inserting into
Column_name Type Computed Length
fileID int no 4
ProcessedOn datetime no 8
ProviderCode nchar no 6
FinancialMonth int no 4
FileName nvarchar no 510
Status nvarchar no 40
Comments nvarchar no 510
This is the Expression code that feeds the SQLStatementSource property
"INSERT INTO FilesProcessed (ProcessedOn, ProviderCode, FinancialMonth,
FileName, Status, Comments) SELECT GETDATE() AS ProcessedOn, '"
+ #[User::providerCode] + "' , "
+ (DT_STR,6,1252)#[User::financialMonth] + ", '"
+ #[User::fileName] + "', 'Imported' AS Status,'Successfully' AS Comments "
Unfortunately I'm missing something, and can't quite get it to work.
The Error message I'm getting is ...
Error: 0xC002F210 at Log entry in
FilesProcessed, Execute SQL Task:
Executing the query "INSERT INTO
FilesProcessed (ProcessedOn,
ProviderCode, FinancialMonth,
FileName, Status, Comments) SELECT
GETDATE(), 'ABC' , 201006,
'DAG_201005_Testology.csv',
'Imported','Successfully'" failed with
the following error: "An error
occurred while extracting the result
into a variable of type (DBTYPE_I2)".
Possible failure reasons: Problems
with the query, "ResultSet" property
not set correctly, parameters not set
correctly, or connection not
established correctly.
Please
a). Advise whether the Execute SQL Task is the way to do what I want to do.
b). Give me any pointers or pitfalls to look out for and check.
Thanks in advance.
OK, here is what I did.
I created an Execute SQL task and configured, thus :-
General Tab
ConnectionType = OLE DB
SQLSourceType = Direct Input
SQLStatement = (left blank)
BypassPrepare = True
ResultSet = None
Parameter Mapping
(none - leave blank)
Result Set
(none - leave blank)
Expressions
SQLStatementSource = "INSERT INTO FilesProcessed (ProcessedOn, ProviderCode, FinancialMonth, FileName, Status, Comments) SELECT GETDATE(), '" + #[User::providerCode] + "' , " + (DT_STR,6,1252)#[User::financialMonth] + ", '" + #[User::fileName] + "', 'Import - Success', '" + #[User::fileComments] + "'"
Then as long as I set up the variables and populate them in the variables window (the Expression editor will not let you save an expression that references a variable that does not exist. Keep notepad handy to store the contents while you go back and edit the variables window, and add new variables in ;)
Build the expression slowly, using the Parse expression button regularly to check.
make sure that the data types of the VALUES match the destination column data types.
see: http://social.msdn.microsoft.com/forums/en-US/sqlintegrationservices/thread/e8f82288-b980-40a7-83a6-914e217f247d/
A couple of speculative suggestions
The Error message says An error occurred while extracting the result into a variable of type (DBTYPE_I2). But this is a straight insert statement. There shouldn't be a result except for rows affected. Do you have any parameter mappings erroneously set to Output?
What if you try and run the SQL Query from the error message directly in management studio? Does that give you an error?
In the above table definition FinancialMonth as int datatype as
FinancialMonth int no 4
while inseting casting as :
(DT_STR,6,1252)#[User::financialMonth]
I think it's purely a datatype mismatch with the target table definition.

Resources