استنادًا إلى تحديد ، يمكنني إرجاع صفوف x مثل هذا:
1 2019-07-23 10:14:04.000
1 2019-07-23 10:14:11.000
2 2019-07-23 10:45:32.000
1 2019-07-23 10:45:33.000
لدينا كل مللي ثانية مع 0.
هل هناك طريقة لإضافة 1 في 1 ميلي ثانية ، لذلك سيبدو التحديد كما يلي:
1 2019-07-23 10:14:04.001
1 2019-07-23 10:14:11.002
2 2019-07-23 10:45:32.003
1 2019-07-23 10:45:33.004
أحاول إنشاء مؤشر أو حتى تحديث دون نجاح.
هذا هو الاستعلام للحصول على النتائج التي أريدها:
select top 10 ModifiedOn
from [SCHEMA].[dbo].[TABLE]
where FIELD between '2019-07-23 00:00' and '2019-07-23 23:59'
هناك قيم 81 كيلو. الحقل DATETIME
.
Datetime
ليس دقيقًا لمستوى 1 مللي ثانية. ما تطلبه غير ممكن ما لم تغير إلى نوع بيانات مختلف (أي datetime2
).
اقتباس مهم:
تم تقريب الدقة إلى زيادات قدرها .000 أو .003 أو .007 ثانية
وظيفة DateAdd
هي ما تبحث عنه.
استخدم millisecond
كمعلمة أولى للدالة ، لإخبارها بأنك تضيف مللي ثانية. ثم استخدام 1
كمعلمة ثانية لعدد المللي ثانية المطلوب إضافتها.
هنا مثال ، جذب الوقت الحالي إلى متغير ، ثم إضافة ملي ثانية إليه وحفظ النتيجة كمتغير ثانٍ ، ثم طباعة كل متغير
Declare @RightNow as DateTime2
Declare @RightNowPlusAMillisecond as DateTime2
Select @RightNow = Getdate()
Select @RightNowPlusAMillisecond = DateAdd(millisecond,1,@RightNow)
Print @RightNow
Print @RightNowPlusAMillisecond
النتائج:
2019-07-23 08:25:38.3500000
2019-07-23 08:25:38.3510000
ملحوظة:
كما يشير فورست في إجابة أخرى ، فإن نوع البيانات datetime
لا يضمن الدقة بالمللي ثانية. يتم تقريبه بزيادات .000 أو .003 أو .007 ثانية. إذا كنت تريد دقة ملي ثانية ، استخدم datetime2
.
@ Doug-Deden لديه نقطة البداية الصحيحة ، لكني أردت فقط محاولة الإجابة عما اعتقدت أنه النية الأصلية للسؤال - كيفية تطبيقه على مجموعة النتائج مع زيادة المللي ثانية في الصف.
في هذه الحالة ، يمكنك استخدام ROW_NUMBER و تعبير الجدول العام (تحرير حسب الحاجة لبنية الجدول ، بما في ذلك الصلات ، وما إلى ذلك).
حدد لإظهار القيم:
;WITH CTE AS (
SELECT t.my_id, t.my_date_column, ROW_NUMBER() OVER (ORDER BY my_date_column, my_id DESC) AS R
FROM Table1 t
)
SELECT TOP 1000 *, DATEADD(MILLISECOND, R, CAST(my_date_column AS datetime2)) [new_date]
FROM CTE
ORDER BY my_date_column
ينضم التحديث إلى الجدول الأصلي:
;WITH CTE AS (
SELECT t.my_id, t.my_date_column, ROW_NUMBER() OVER (ORDER BY my_date_column, my_id DESC) AS R
FROM Table1 t
)
UPDATE t SET
my_date_column = DATEADD(MILLISECOND, R, CAST(my_date_column AS datetime2))
FROM CTE c
JOIN Table1 t ON c.my_id = t.my_id
لقد فعلت ذلك باستخدام DATETIME2(3)
.
كما ترى في الاستعلام أدناه ، فهو أكثر economic
:
declare @dt1 datetime2(3)
declare @dt2 datetime2
SELECT @DT1 = SYSDATETIME()
SELECT @DT2= SYSDATETIME()
SELECT [THE LENGTH OF DATETIME2]=DATALENGTH(@DT2)
,[THE LENGTH OF DATETIME2(3)]=DATALENGTH(@DT1)
يتم شرح الاختلافات بين datetime
و datetime2
جيدًا هنا .
في هذا التمرين ، أقوم بإنشاء جدول مؤقت لأغراض الاختبار ، وقم بتعبئته بـ 999 random dates
مختلفة من 01-jan-2019
واليوم (23-july-2019
)
وبعد ذلك ، قمت بتعيين المللي ثانية من 1 إلى 999
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOEXEC OFF
IF OBJECT_ID ('TEMPDB..#T1') IS NOT NULL
DROP TABLE #T1
CREATE TABLE #t1(the_date DATETIME2(3) NOT NULL PRIMARY KEY CLUSTERED )
GO
-- run this 999 times - hopefully there will be no duplicates
-- SELECT 204*24*60*60 - today is 23-july-2019 - the 203rd day of the year
DECLARE @DT DATETIME2(3)
SELECT @DT = CONVERT(DATETIME2(3),
DATEADD(SECOND, ABS(CHECKSUM(NEWID()) % 17625600),
'2019-01-01'),120)
--SELECT @DT
IF NOT EXISTS( SELECT 1 FROM #T1 WHERE THE_DATE = @DT)
INSERT INTO #T1 VALUES (@DT)
GO 999
--check it out what we have
SELECT * FROM #T1
--get the date and the new date
SELECT
THE_DATE
,THE_NEW_DATE= DATEADD(MILLISECOND, ROW_NUMBER() OVER (ORDER BY THE_DATE), THE_DATE )
FROM #T1
وهذا ما أحصل عليه: (منظر جزئي)
أحد الملصقات الأخرى صحيح ؛ DATETIME
(في T-SQL) ليست دقيقة بالمللي ثانية (إنها دقيقة بالملي ثانية).
لهذا المستوى من الدقة ، تريد استخدام DATETIME2
.
هنا مثال على تحويل سلسلة datetime
إلى datetime2
، ثم إضافة 1 مللي ثانية ، وأخيرًا ، التحويل مرة أخرى إلى سلسلة.
select convert(
varchar(MAX), --in T-SQL, varchar length is optional
dateadd(
millisecond,
1,
convert(
datetime2,
'2019-07-23 12:01:23.11'
)
)
)