Bagaimana cara menambahkan menit ke tipe data waktu?

10

Saya memiliki prosedur tersimpan yang memasukkan dua catatan ke dalam tabel, perbedaan antara catatan adalah bahwa kolom waktu dari catatan kedua adalah @MinToAddsetelah yang pertama:

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

Apa cara yang benar untuk menambahkan @MinutesToAddmenit ke @StartTimedan @EndTime?
Harap dicatat saya menggunakan timetipe data.

Pembaruan :
Jawaban yang benar harus berisi informasi berikut:

  • Cara menambahkan menit ke timetipe data.
  • Bahwa solusi yang diusulkan tidak mengakibatkan hilangnya presisi.
  • Masalah atau kekhawatiran yang harus diperhatikan jika risalah terlalu besar untuk dimasukkan ke dalam timevariabel, atau risiko tergulingnya timevariabel. Jika tidak ada masalah maka harap sebutkan.
Berbilah
sumber
5
Saya tidak melihat bagaimana hasil edit Anda untuk pertanyaan Anda semakin memperjelas pertanyaan yang ada.
swasheck
@swasheck Saya secara eksplisit menyatakan tiga hal yang saya cari. Saya juga menetapkan batasan pada apa yang tidak saya cari.
Ditebangi

Jawaban:

36

Anda tidak dapat menggunakan aritmatika steno malas dengan tipe baru. Mencoba:

DATEADD(MINUTE, @MinutesToAdd, @StartTime)

Perhatikan bahwa meskipun Anda telah melindungi @MinutesToAdddari luapan, Anda belum melindungi hasilnya dari luapan. Ini tidak menghasilkan kesalahan, namun, mungkin bukan hasil yang Anda harapkan.

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

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

Hasil:

00:19:00

Saya berasumsi ini harus melalui beberapa jenis konversi internal, karena Anda tidak bisa mendapatkan hasil itu dengan mengatakan:

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

Hasil:

Msg 241, Level 16, State 1, Line 1
Konversi gagal ketika mengubah tanggal dan / atau waktu dari string karakter.

Anda perlu mempertimbangkan bagaimana Anda ingin menangani perhitungan yang mengarah ke salah satu @EndTimeatau keduanya @StartTimedan @EndTimeberada di hari berikutnya.

Juga - untuk memenuhi persyaratan baru lainnya dalam "jawaban ideal" Anda - tidak ada kehilangan presisi. Sesuai dokumentasi , jenis DATEADDpengembalian sama dengan input:

Tipe data kembali adalah tipe data dari argumen tanggal , kecuali untuk string literal.

Karena itu, TIMEmasuk, TIMEkeluar.

Aaron Bertrand
sumber
1
+1 @Aaron Atau Anda dapat mengonversi StartTime dan TimeToAdd ke datetime lalu menambahkan. Konversi TimeToAdd akan sangat berantakan ketika risalah> 59. DATEADD adalah solusi terbaik.
Brian
Jika Anda menambahkan bahwa DATEADDmengembalikan jenis yang sama dengan argumen tanggal maka saya akan menerimanya. "Cegah luapan jika perlu?" garis tidak diperlukan. Masalah roll over akan ditangani oleh sumber data dan tujuan data.
Dipotong
3
@Trisped yakin, jika Anda menambah pertanyaan yang menurut Anda DATEADD tidak tepat karena Anda pikir itu hanya dapat mengembalikan DATETIME dan itu dapat menyebabkan masalah. Kalau tidak, sepertinya tidak relevan dengan pertanyaan Anda atau bagi pembaca di masa depan ...
Aaron Bertrand
Bagaimana relevansi yang tidak tersirat oleh "Harap dicatat saya menggunakan tipe data waktu."? Juga, mengapa Anda mengubah pertanyaan saya untuk menggunakan baris bukannya rekaman secara tidak langsung?
Dipotong
1
@Trisped hasil pengeditan menggunakan terminologi yang lebih baik dan silakan lihat faq tentang pengeditan —saya tidak memiliki bolak-balik atau saya akan mengunci pertanyaan. Aaron benar bahwa kami perlu membuat segalanya jelas bagi orang lain, Anda memiliki jawaban Anda. Silakan pertimbangkan untuk mengedit pertanyaan Anda sesuai dengan sarannya jika Anda pikir itu akan membantu: Aaron telah dengan ramah menawarkan untuk menambahkan informasi yang Anda inginkan ke jawabannya jika Anda melakukannya.
Jack bilang coba topanswers.xyz
0

Cukup gunakan fungsi dateadd untuk menambahkan menit Anda dalam bilangan bulat terhadap '0:00'. Lalu kembalikan ke waktu.

Pilih cast (dateadd (menit, 84, '0: 00') sebagai waktu)

Di sini, 84 adalah menit integer yang ingin saya ungkapkan dalam tipe "waktu".

Saya menambahkannya ke '0:00' dan kemudian untuk menghapus komponen tanggal, saya memasukkannya ke tipe waktu. Tidak perlu pengkodean khusus.

(Tidak ada nama kolom)

01: 00.00.0000000

Jun Sato
sumber