I need to insert a datetime value into datetime column in SQL Server 2005
I am passing DateTime variable from the .aspx page
Which needs to be inserted in the column.
Example:
Table(date datetime)
#sql = 'insert into Table (date) values('+#datetime+')'
exec(#sql)
getting conversion failed message.
Any idea how to do this.
Very Urgent.
Thanks.
You need string delimiters - in T-SQL this is doubled-up single quotes.
SET #sql = 'insert into Table (date) values('''+#datetime+''')'
exec(#sql)
However it still might fail, depending on the format of the string. Any reason you're building a SQL string, prone to SQL injection, instead of just saying:
INSERT Table(date) SELECT #datetime;
?
Add escaped single quotes around the datetime value. Normally they are passed as strings.
See if this works:
#sql = 'insert into Table (date) values('''+#datetime+''')'
exec(#sql)
Make sure your query/stored procedure are expecting to receive the parameter as a datetime variable (not varchar(20), or anything else like that), and make sure your ASP.Net code is passing the value as a datetime value also.
Basically, for best datetime handling, convert them from strings into datetimes as early as possible when accepting them as input (e.g. convert them in an appropriate event in your code behind in ASP.NET), keep them as datetimes whenever passing them to/from the database, and fromat them back as strings as late as possible when outputting them (e.g. in view code for asp.net mvc, or when assigning to the Text property of an ASP.Net control)
Besides the other suggestions with delimiters and parenthesis mismatches, Date is a reserved keyword, use [Date] instead.
Try making this small change to your sql statement
#sql = "insert into Table (date) values ('"+ #datetime + "')"
Declare #datetime datetime
Set #datetime=GetDate()
Declare #sql nvarchar(1000)
Declare #param nvarchar(1000)
Set #param='#datetime datetime'
SET #sql = 'insert into Table (date) values(#datetime)'
exec sp_executesql #sql,#param,#datetime
you have to learn the sql injection for dynamic queries.
Related
I have column of type of datetime, that I am using in my stored procedure by declaring the two local variables as #From datetime and #To datetime, but no matter what I do I get the error or it simply run the stored procedure without returning any records(completely blank).
set #mySql ='
select * from abc where (MyDATE between '''+ cast(#From as datetime) +''' and '''+ cast(#To as datetime)+''')'
The only "correct" way to do this is to preserve them as parameters inside the dynamic SQL. For example:
set #mySql =N'select * from abc where MyDATE between #from and #to';
exec sp_executesql #mySql, N'#from datetime, #to datetime', #fromOuter, #toOuter;
This keeps them correctly typed in the dynamic code, and avoids both formatting concerns and SQL injection risks. Note that the names inside and outside the dynamic code do not need to match, as shown in the example above (#from and #to are the names in the dynamic code; #fromOuter and #toOuter are the names in the calling code).
Note that it doesn't matter if you pass in more parameters than you actually use (this would be pretty normal for a dynamic filtering method).
Try to keep your data in variables of the appropriate type, whenever possible.
For instance, here you can do:
--#From and #To are declared previously as datetimes
set #mySql ='select * from abc where (MyDATE between #From and #To)'
--Other code that constructs/works on #mySQL
--Finally, run the dynamic sql:
EXEC sp_executesql #mySql,
'#From datetime,#To datetime`,
#From,
#To
And everything should work beautifully because you're not forcing back and forth between strings and datetimes, and its those conversions that introduce the opportunity to have formatting issues.
the issue here is that when you are building the Dynamic SQL, you are looking to cast your parameters as DateTime.
What you should actually do is avoid the use of casting. Set the Parameters as date time and store required values before you use them to build your dynamic SQL Statement.
I am trying to use some dynamic sql. I have generated over 100 parameters, and to speed things up I am trying to use dynamic sql to only insert values into a table that I have to based off of information retrieved from other tables. I have tried many things like adding a cast etc.
Example of what I mean:
DECLARE #var1 NVARCHAR(MAX)
-- Loop through and add various values
SET #var1 = #var1 + #parameterName
-- The parameter name is retrieved from a table that holds this information
the problem is that when I add the parameter name which would be like "#myFirstParameter" into my final expression so something like this:
DECLARE #finalString NVARCHAR(MAX)
SET #finalString = 'INSERT INTO myTableName ([myFirstParameter]) VALUES (#myFirstParameter)'
EXEC(#finalString)
The "#myFirstParameter" does not get replaced by it's value and I get the following error:
Must declare the scalar variable "#myFirstParameter".
Does anyone know of a way to go from the string name of a parameter to the actual value? I am trying to avoid hardcoding all the values and any work around I have attempted has failed and given me errors which appear to be much worse than what I have stated above.
The first way is to add the parameter's value, instead of its name, to the SQL string:
SET #finalString = 'INSERT INTO myTableName ([myFirstParameter]) VALUES (' +
#myFirstParameter + ')'
This assumes the parameter has a string value. If not, you have to cast it, like cast(#myFirstParameter as varchar(128)).
The second way is to use sp_executesql instead of exec:
exec sp_executesql
N'INSERT INTO myTableName ([myFirstParameter]) VALUES (#myFirstParameter)',
N'#myFirstParameter varchar(128)',
#myFirstParameter = #myFirstParameter;
I am new to both SQL 2005 and Enterprise Library (version 4.) I'd like to call a Stored Proc and pass a string that is over 8000 chars. The column in the db is defined as varchar(max). I thought I'd start out by doing a little test first with calling the stored proc from T-SQL and I was surprised that the inserted string value was truncated, even for a short string.
CREATE TABLE [dbo].[ChadTest](
[TestParam] [varchar](max) NOT NULL
) ON [CMISII_DATA]
GO
ALTER PROCEDURE [dbo].[spr_ChadTest]
(
#TestParam varchar(max)
)
AS
BEGIN
INSERT INTO ChadTest
(TestParam) VALUES (#TestParam)
END
DECLARE #RC int
DECLARE #TestParam varchar
-- TODO: Set parameter values here.
SET #TestParam = '12345'
EXECUTE #RC = [CMISII].[dbo].[spr_ChadTest]
#TestParam
Select TestParam, len(TestParam) from chadtest
Output:
1 1
Once I get this simple example above to work, I will need to figure out how to pass a long string to the SP from VB.NET code using the Enterprise library . What would the data type of the param be? I see no overloaded version of the AddInParameter method that accepts a length nor do I see a "varchar(max)" enum as an available data type.
dbCmd = db.GetStoredProcCommand("spr_ChadTest")
db.AddInParameter(dbCmd, "TestParam", SqlDbType.VarChar, TestParam.ToString)
Thanks!
DECLARE #TestParam varchar
is the problem in your TSQL. You need to declare that as varchar(max) datatype to avoid truncation at 1 character length.
Your variable definition for TestParam is missing the (MAX) at the end of it. This will resolve your SQL query problem. The following code will add a paramter to a SqlCommand allowing the use of VARCHAR(MAX) from a VB .Net ASP application.
' Set up the output parameter to retrieve the summary.
Dim paramSummary As SqlParameter = New SqlParameter("#TestParam", SqlDbType.VarChar, -1)
command.Parameters.Add(paramSummary)
The following link displays more information
please help me with writing this search sql stored procedure
procedure may have different number of parameters at different time
so could any body help me with writing this query. I don't know how to concatenate parameters.
i am new to stored procedure
CREATE PROCEDURE searchStudent
-- Add the parameters for the stored procedure here
#course int=null,
#branch int=null,
#admissionYear varchar(max)=null,
#passingYear varchar(max)=null,
#userName varchar(max)=null,
#sex varchar(max)=null,
#studyGap varchar(max)=null,
#firstName varchar(max)=null,
#lastName varchar(max)=null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE query STR DEFAULT null
IF #course IS NOT NULL
THEN query=
SELECT * FROM [tbl_students] WHERE
END
GO
please complete the query so that it can have parameters which are having values and can search from database on the basis of parameters value. But parameter may vary every time depends on search criteria.
You would probably need to use Dynamic SQL to achieve this. First of all I would highly recommend reading this excellent article. http://www.sommarskog.se/dynamic_sql.html
You're dynamic sql would be something like this;
Declare #query varchar(max)
Set #query = 'Select * From dbo.MyTable Where '
If #Course Is Not Null
Begin
Set #query = #query + 'Course = ' + Convert(varchar(10), #Course)
end
If #Branch Is Not Null
Begin
Set #query = #query + ' and Branch = ' + Convert(varchar(10), #Branch )
end
This is only an example! You will need to build in some checks to ensure that you have one (and only one) Where clause, you must ensure that the integer values are converted to string values correctly. You must also check that the parameters don't have any special characters that could break the dynamic sql - like an apostrophe (')
Using dynamic SQL can be painful and very difficult to get right.
Good luck!
The key with a dynamic search conditions is to make sure an index is used, instead of how can I easily reuse code, eliminate duplications in a query, or try to do everything with the same query. Here is a very comprehensive article on how to handle this topic:
Dynamic Search Conditions in T-SQL by Erland Sommarskog
It covers all the issues and methods of trying to write queries with multiple optional search conditions. This main thing you need to be concerned with is not the duplication of code, but the use of an index. If your query fails to use an index, it will preform poorly. There are several techniques that can be used, which may or may not allow an index to be used.
here is the table of contents:
Introduction
The Case Study: Searching Orders
The Northgale Database
Dynamic SQL
Introduction
Using sp_executesql
Using the CLR
Using EXEC()
When Caching Is Not Really What You Want
Static SQL
Introduction
x = #x OR #x IS NULL
Using IF statements
Umachandar's Bag of Tricks
Using Temp Tables
x = #x AND #x IS NOT NULL
Handling Complex Conditions
Hybrid Solutions – Using both Static and Dynamic SQL
Using Views
Using Inline Table Functions
Conclusion
Feedback and Acknowledgements
Revision History
Sorry, I am having trouble understanding what you are asking. Do you mean the consumer of the sproc may specify some arbitrary subset of the parameters and you want to filter on those?
Assuming the above you have 2 options.
1.
use a where clause something like this:
WHERE ([tbl_students].firstName = ISNULL(#firstname,firstName)
AND ([tbl_students].lastName = ISNULL(#lastName ,lastName )
etc.
What this does is check if your parameter has a value, and, if so, it will compare it to the column. If the param is null, then it will compare the column to itself, which will never filter anything out.
use dynamic sql in your sproc and just include the line of the where clause you want if the param is not null.
I am trying to write a database script (SQL Server 2008) which will copy information from database tables on one server to corresponding tables in another database on a different server.
I have read that the correct way to do this is to use a sql statement in a format similar to the following:
INSERT INTO <linked_server>.<database>.<owner>.<table_name> SELECT * FROM <linked_server>.<database>.<owner>.<table_name>
As there will be several tables being copied, I would like to declare variables at the top of the script to allow the user to specify the names of each server and database that are to be used. These could then be used throughout the script. However, I am not sure how to use the variable values in the actual SQL statements. What I want to achieve is something like the following:
DECLARE #SERVER_FROM AS NVARCHAR(50) = 'ServerFrom'
DECLARE #DATABASE_FROM AS NVARCHAR(50) = 'DatabaseTo'
DECLARE #SERVER_TO AS NVARCHAR(50) = 'ServerTo'
DECLARE #DATABASE_TO AS NVARCHAR(50) = 'DatabaseTo'
INSERT INTO #SERVER_TO.#DATABASE_TO.dbo.TableName SELECT * FROM #SERVER_FROM.#DATABASE_FROM.dbo.TableName
...
How should I use the # variables in this code in order for it to work correctly?
Additionally, do you think my method above is correct for what I am trying to achieve and should I be using NVARCHAR(50) as my variable type or something else?
Thanks
There is probably a better way to do this, but what you are probably trying to do in your example is what's called dynamic SQL where you treat the statement as a string and the execute it. This would be section #2 here:
http://www.mssqltips.com/tip.asp?tip=1160
There are some major downsides to dynamic SQL. You see a couple other approaches that might be better in that article.
If you want to execute a dynamically generated query then you have to use sp_ExecuteSQL
HTH
For the nvarchar(50) - you'd be better using sysname. This is a synonym in SQL Server (for nvarchar(128)) and represents the maximum length of an object identifier.
have a look at http://msdn.microsoft.com/en-us/library/ms188001.aspx - sp_executesql takes a parameter that is a string and executes the sql in that string. so you'd need to concatenate #SERVER_FROM and other params with the INSERT INTO part to make the entire sql statement, and then pass to sp_executesql.
nvarchar(50) is fine, unless your server/database names are longer than that :)
You can create the select statement by concatenating all the information together and then use sp_executesql
so:
sp_executesql 'INSERT INTO ' + #SERVER_TO + '.' + #DATABASE_TO +
'.dbo.TableName SELECT * FROM ' + #SERVER_FROM + '.' +
#DATABASE_FROM+'.dbo.TableName'
I like to make templates for dynamic SQL things like this - it's a lot easier to maintain complex statements and also sometimes easier to handle nested quotes - and definitely easier when terms need to be repeated in multiple places (like column lists):
DECLARE #sql AS nvarchar(max);
SET #sql = 'INSERT INTO {#SERVER_TO}.{#DATABASE_TO}.dbo.TableName
SELECT *
FROM {#SERVER_FROM}.{#DATABASE_FROM}.dbo.TableName'
SET #sql = REPLACE(#sql, '{#SERVER_TO}', QUOTENAME(#SERVER_TO))
SET #sql = REPLACE(#sql, '{#DATABASE_TO}', QUOTENAME(#DATABASE_TO))
SET #sql = REPLACE(#sql, '{#SERVER_FROM}', QUOTENAME(#SERVER_FROM))
SET #sql = REPLACE(#sql, '{#DATABASE_FROM}', QUOTENAME(#DATABASE_FROM))
EXEC(#sql)