ฉันจะเพิ่มนาทีในประเภทข้อมูลเวลาได้อย่างไร


10

ฉันมีขั้นตอนการจัดเก็บที่แทรกสองระเบียนลงในตารางความแตกต่างระหว่างบันทึกคือคอลัมน์เวลาของระเบียนที่สองอยู่@MinToAddหลังแรก:

CREATE PROCEDURE CreateEntry
    /*Other columns*/
    @StartTime time(2),
    @EndTime time(2),
    @MinutesToAdd smallint
    AS
BEGIN
    SET NOCOUNT ON;

    SET @MinutesToAdd = @MinutesToAdd % 1440;   --Prevent overflow if needed?
    IF (@MinutesToAdd > 0)
    BEGIN
    INSERT INTO ClientNotification (/*Other columns*/ startTime, endTime)
        OUTPUT inserted.id
        VALUES
               (/*Other columns*/ @StartTime, @EndTime),
               (/*Other columns*/ @StartTime + @MinutesToAdd, @EndTime + @MinutesToAdd);
    END
    ELSE
    BEGIN
        /*Whatever ELSE does.*/
    END
END

วิธีที่ถูกต้องในการเพิ่ม@MinutesToAddนาที@StartTimeและ@EndTimeคืออะไร?
โปรดทราบฉันกำลังใช้timeประเภทข้อมูล

อัปเดต :
คำตอบที่ถูกต้องควรมีข้อมูลต่อไปนี้:

  • วิธีเพิ่มนาทีในtimeประเภทข้อมูล
  • การที่โซลูชันที่เสนอนั้นไม่ส่งผลให้สูญเสียความแม่นยำ
  • ปัญหาหรือข้อกังวลที่ควรระวังในกรณีที่นาทีนั้นมีขนาดใหญ่เกินไปที่จะพอดีกับtimeตัวแปรหรือมีความเสี่ยงในการหมุนtimeตัวแปร หากไม่มีปัญหากรุณาระบุให้

5
ฉันไม่เห็นว่าการแก้ไขคำถามของคุณจะทำให้คำถามชัดเจนขึ้นได้อย่างไร
swasheck

@swasheck ฉันระบุสามสิ่งที่ฉันต้องการอย่างชัดเจน ฉันยังกำหนดขอบเขตสิ่งที่ฉันไม่ต้องการ
เดินขบวน

คำตอบ:


36

คุณไม่สามารถใช้เลขคณิตชวเลขขี้เกียจกับประเภทใหม่ได้ ลอง:

DATEADD(MINUTE, @MinutesToAdd, @StartTime)

โปรดทราบว่าแม้ว่าคุณได้ป้องกัน@MinutesToAddจากการล้น แต่คุณยังไม่ได้ป้องกันผลลัพธ์จากการล้น สิ่งนี้ไม่ได้ทำให้เกิดข้อผิดพลาด แต่อาจไม่ใช่ผลลัพธ์ที่คุณคาดหวัง

DECLARE @StartTime TIME(0) = '23:59';
DECLARE @MinutesToAdd INT = 20;

SELECT DATEADD(MINUTE, @MinutesToAdd, @StartTime);

ผลลัพธ์:

00:19:00

ฉันคิดว่าสิ่งนี้จะต้องผ่านการแปลงภายในบางประเภทเนื่องจากคุณไม่สามารถรับผลลัพธ์ได้โดยพูดว่า:

DECLARE @StartTime TIME(0) = '24:19';

ผลลัพธ์:

ข่าวสารเกี่ยวกับ 241 ระดับ 16 สถานะ 1
การแปลงบรรทัด 1 ล้มเหลวเมื่อแปลงวันที่และ / หรือเวลาจากสตริงอักขระ

คุณต้องพิจารณาว่าคุณต้องการจัดการกับการคำนวณที่นำไปสู่อย่างใดอย่างหนึ่ง@EndTimeหรือทั้งสองอย่าง@StartTimeและ@EndTimeจะเป็นอย่างไรในวันถัดไป

นอกจากนี้ - เพื่อตอบสนองความต้องการใหม่ใน "คำตอบในอุดมคติ" ของคุณ - ไม่มีการสูญเสียความแม่นยำ ตามเอกสารประเภทการส่งคืนของDATEADDเหมือนกับอินพุต:

ชนิดข้อมูลที่ส่งคืนเป็นชนิดข้อมูลของอาร์กิวเมนต์วันที่ยกเว้นตัวอักษรสตริง

ดังนั้นTIMEเข้าTIMEออก


1
+1 @Aaron อีกวิธีหนึ่งคุณสามารถแปลง StartTime และ TimeToAdd เป็น datetime จากนั้นเพิ่ม การแปลง TimeToAdd จะยุ่งมากเมื่อนาที> 59 DATEADD เป็นทางออกที่ดีที่สุด
ไบรอัน

หากคุณเพิ่มที่DATEADDส่งกลับประเภทเดียวกันกับอาร์กิวเมนต์วันที่แล้วฉันจะยอมรับ "ป้องกันล้นหากจำเป็นหรือไม่" ไม่จำเป็นต้องใช้บรรทัด ปัญหาการย้อนกลับจะถูกจัดการโดยแหล่งที่มาของข้อมูลและปลายทางของข้อมูล
ริป

3
@Trisped แน่ใจว่าถ้าคุณเพิ่มคำถามที่คุณไม่คิดว่า DATEADD เหมาะสมเพราะคุณคิดว่ามันสามารถส่งคืน DATETIME เท่านั้นและนั่นอาจทำให้เกิดปัญหา มิฉะนั้นดูเหมือนว่าจะไม่เกี่ยวข้องกับคำถามของคุณหรือสำหรับผู้อ่านในอนาคต ...
Aaron Bertrand

"โปรดทราบว่าฉันกำลังใช้ประเภทข้อมูลเวลา" ไม่เกี่ยวข้องกันอย่างไร นอกจากนี้ทำไมคุณเปลี่ยนคำถามของฉันให้ใช้แถวแทนที่จะบันทึกอย่างไม่ถูกต้อง?
เดินขบวน

1
@Trisped การแก้ไขใช้คำศัพท์ที่ดีกว่าและโปรดดูคำถามที่พบบ่อยเกี่ยวกับการแก้ไข -ไม่ได้มีการย้อนกลับไปมาหรือฉันจะล็อคคำถาม แอรอนพูดถูกที่เราต้องทำให้ทุกอย่างชัดเจนเพื่อคนอื่นคุณมีคำตอบ โปรดพิจารณาแก้ไขคำถามของคุณตามบรรทัดที่เขาแนะนำถ้าคุณคิดว่ามันจะมีประโยชน์: Aaron ได้เสนอที่จะเพิ่มข้อมูลที่คุณต้องการคำตอบของเขาถ้าคุณทำ
แจ็คบอกว่าลอง topanswers.xyz

0

เพียงใช้ฟังก์ชัน dateadd เพื่อเพิ่มจำนวนนาทีของคุณเป็นจำนวนเต็มเทียบกับ '0:00' จากนั้นก็โยนทิ้งไปตามกาลเวลา

เลือก cast (วันที่เพิ่ม (นาที, 84, '0: 00') ตามเวลา)

ที่นี่ 84 คือจำนวนเต็มนาทีที่ฉันต้องการแสดงเป็น "เวลา"

ฉันเพิ่มไปที่ '0:00' จากนั้นเมื่อต้องการลบองค์ประกอบวันที่ฉันใช้มันเป็นประเภทเวลา ไม่จำเป็นต้องเขียนโค้ดเอง

(ไม่มีชื่อคอลัมน์)

01: 24: 00,0000000

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.