I need to store the current time (format 'hi') as char(4) in a table (is created and used by another program, I can't change it) and now wondered what is a suitable way to retrieve it via SQL. I know MySQL is not that standard-orientated, but I thought it could be something similiar to DATE_FORMAT(NOW(), 'Hi'). The code below which I found works, but feels little intricately.
SELECT CAST(DATEPART(hour, GETDATE()) AS nvarchar)+CAST(DATEPART(minute, GETDATE()) AS nvarchar);
Is there a better way to achieve this?
Following gives the same result:
SELECT LEFT(STUFF(CONVERT(NCHAR(8), GETDATE(), 8), 3, 1,''), 4)
It seems to have approximately the same performance as the method from question. I tested it like this:
DECLARE #i INT = 0,
#dto1 DATETIME2,
#dto2 DATETIME2
SET #dto1 = SYSDATETIME()
WHILE #i < 100000
BEGIN
PRINT LEFT(STUFF(CONVERT(NCHAR(8), GETDATE(), 8), 3, 1,''), 4)
SET #i = #i + 1
END
SET #dto2 = SYSDATETIME()
SELECT DATEDIFF(MILLISECOND, #dto1, #dto2)
Sql Server 2008 has a time datatype:
select replace(left(cast(getdate() as time), 5), ':', '')
Related
I wish to replace cca 3 500 000 values in Mysql Table. Each value is string in the form of AB00123012 and I wish to remove leading zeroes after letters - i.e. get AB123012 (zeroes inside number should be kept).
The value has always exactly 10 characters.
Since Mysql does not allow replace by regex, I have used following function:
DELIMITER $$
CREATE FUNCTION fn_RawRingNumber (rn CHAR(10))
RETURNS CHAR(10) DETERMINISTIC
BEGIN
DECLARE newrn CHAR(10);
DECLARE pos INT(8);
DECLARE letters CHAR(2);
DECLARE nr CHAR(8);
IF (CHAR_LENGTH(rn) = 10) THEN
SET pos = (SELECT POSITION('0' IN rn));
SET letters = (SELECT SUBSTRING_INDEX(rn, '0', 1));
SET nr = (SELECT TRIM(LEADING '0' FROM SUBSTRING(rn,pos)));
SET newrn = (SELECT CONCAT(letters, nr));
ELSE
SET newrn = rn;
END IF;
RETURN newrn;
END$$
DELIMITER ;
While this works, it is rather slow and I am wondering, if there is not a better way to do this?
If you can afford to take your site offline for a few minutes, the fastest way would be to dump, process and re import. Since the current operation makes queries/inserts on that table pretty slow, so you are probably better off with a dump/process/import anyway.
Step 1 dump.
SELECT INTO OUTFILE is your friend here
Step 2 process
Use your favourite programming language or if you are lucky to be on linux, something like sed or even cut. If you need help with the regex post a comment.
Step 3 reimport
After clearing out the table. Do a LOAD DATA INFILE.
these three steps should all be reasonably quick. Specially if you have a n index on that column.
Try this
Note: I not tested this with many rows and don't know how this is efficient.
Also, if this is fast, please before using this, think all possible variations, which may occurs with your string, may be I missed some variants, not sure 100%.
select case
when INSTR(col, '0') = 2 then concat( substr(col, 1, 1), substr(col, 2) * 1)
when INSTR(col, '0') = 3 and substr(col, 2, 1) not in('1','2','3','4','5','6','7','8','9') then concat( substr(col, 1, 2), substr(col, 3) * 1)
else col
end
from (
select 'AB00123012' as col union all
select 'A010000123' as col union all
select 'A1000000124' as col union all
select 'A0000000124' as col union all
select '.E00086425' as col
) t
We've been experiencing some severe performance issues on our SQL 2008 r2 DB. When we run the Activity Monitor in SQL Server Management Studio, and a SP that returns who/what is active, it shows the following three transactions as being very expensive:
Query 1:
SET #DateMonth = '0' + #DateMonth
Query 2:
SET #DateMonth = CAST(datepart(mm, #TheDate) AS VARCHAR(2))
Function:
CREATE FUNCTION [dbo].[DateToNGDate] (#TheDate datetime)
RETURNS VARCHAR(10)
AS
BEGIN
DECLARE #DateYear VARCHAR(4)
DECLARE #DateMonth VARCHAR(2)
DECLARE #DateDay VARCHAR(2)
SET #DateYear = CAST(datepart(yyyy, #TheDate) AS VARCHAR(4))
SET #DateMonth = CAST(datepart(mm, #TheDate) AS VARCHAR(2))
IF (LEN (#DateMonth) = 1) SET #DateMonth = '0' + #DateMonth
SET #DateDay = CAST(datepart(dd, #TheDate) AS VARCHAR(2))
IF (LEN (#DateDay) = 1) SET #DateDay = '0' + #DateDay
RETURN #DateYear+#DateMonth+#DateDay
END
That last one comes back like that, but i'm pretty sure it isn't creating the function (it already exists), rather it is just running it. It is also the one that comes up the most as appearing to be a performance killer (it's used throughout our code).
I'm sure these aren't what is actually causing the problem, but why would they appear as they are?
Scalar-valued functions are a known performance issue in SQL Server. One option is to define your function like this:
CREATE FUNCTION [dbo].[DateToNGDateX] (#TheDate datetime)
RETURNS table as return
(
select
cast(
CAST(datepart(yyyy, #TheDate) AS VARCHAR(4)) -- DateYear
+ right('0' + CAST(datepart(mm, #TheDate) AS VARCHAR(2)),2) -- DateMonth
+ right('0' + CAST(datepart(dd, #TheDate) AS VARCHAR(2)),2) -- DateDay
as varchar(30)) as Value
)
and reference it like this:
select Value from [dbo].[DateToNGDateX] ('20140110');
However, for the specific functionality you desire, test this as well:
select convert(char(8), cast('20140110' as date), 112);
which will return a date formatted as yyyymmdd.
Scalar UDFs are very slow if your select statement is returning a lot of rows, because they are going to be executed once for every row that is returned. Maybe you can rewrite as an inline function as per this link inline UDFs
I like Pieter Geerkens answer and I hope it has resolved your problem. The scalar function will return results for each of the matching rows wherever it is being used. So it is something similar to cursors. A table valued function will accept a set and return a set.
To verify the I\O changes between both processes, management studio might not help but on your own machine you can put a small trace to see what magnitude of performance you get.
Cheers!!
I am trying to convert varchar to datetime.
SELECT
CONVERT(DATETIME, CONVERT(VARCHAR, YEAR(GETDATE())) + '/' +
CONVERT(VARCHAR, MONTH(GETDATE())) + '/' +
CONVERT(VARCHAR, DAY(GETDATE()) + 27), 120)
I am expecting the result
2012-07-02 00:00:00.000
But my script is throwing an error.
Please anyone help me.
Thanks
Gurej
Why are you starting with a datetime, munging it to varchar and then casting back to datetime?
Is your real question, "How do I remove the time portion of a datetime?"
If so, you do it like this:
select DATEADD(day, DATEDIFF(day, 0, getdate()), 0)
Or SQL Server 2008 onwards, simply:
select cast(CAST(getdate() as date) as datetime)
Or even, declare the underlying variable/column as date, and use
select CAST(getdate() as date)
Hi is there any simple way to convert hours to seconds? by using sql query.
Ex: #mytime = 2:15 hours
expected output is #result = 8100 seconds.
2 * 3600 + 15 * 60 = 8100
Thanks
You already presented the simplest way 8-)
If you want to convert hour string, then:
DECLARE #str VARCHAR(10) = '5:35'
SELECT
CAST(SUBSTRING(#str, 1, CHARINDEX(':', #str, 1)-1) AS INT)*3600+
CAST(SUBSTRING(#str, CHARINDEX(':', #str, 1)+1, 1000) AS INT)*60
There is a simpler way that works in SQL server and is less error prone.
DECLARE #str CHAR(5) = '02:15'
SELECT
DATEDIFF(SECOND, '00:00', #str)
I'm having the same problem as described here, unfortunately the solution does not work for MS SQL Server.
Does a similar syntax exist for MS SQL Server?
Note: my query is not as simple as in the example. I'd like to reuse DifferenceMinutes in the TooLateTime case.
DATEDIFF(MINUTE, DayOfWeekStopTime, GETDATE()) AS DifferenceMinutes,
CASE
WHEN DATEDIFF(MINUTE, DayOfWeekStopTime, GETDATE()) < 0 THEN NULL
ELSE CONVERT(varchar, GETDATE() - DayOfWeekStopTime, 108)
END AS TooLateTime
It's a little hard to tell exactly what you're trying to do, but I think this might be what you're looking for:
SELECT
DifferenceMinutes,
CASE
WHEN DifferenceMinutes < 0 THEN NULL
ELSE CONVERT(varchar, GETDATE() - DayOfWeekStopTime, 108)
END AS TooLateTime
FROM (
SELECT
DayOfWeekStopTime,
DATEDIFF(MINUTE, DayOfWeekStopTime, GETDATE()) AS DifferenceMinutes
FROM TableName
) X
You'll have to substitute your source table(s) for "TableName" in the FROM section of the inner query.
By rolling your calculated values into a nested select like this, you can refer to them by whatever name you give them in the outer query.
If you want to set variables for each of the values, you can do that as follows, but you'll need to make sure you're only returning one row from the query:
DECLARE #DifferenceMinutes int, #TooLateTime varchar(30)
SELECT
#DifferenceMinutes = DifferenceMinutes,
#TooLateTime = CASE
WHEN DifferenceMinutes < 0 THEN NULL
ELSE CONVERT(varchar, GETDATE() - DayOfWeekStopTime, 108)
END
FROM (
SELECT
DayOfWeekStopTime,
DATEDIFF(MINUTE, DayOfWeekStopTime, GETDATE()) AS DifferenceMinutes
FROM TableName
) X