DTECH SST - Tài liệu kỹ thuật
  • CÀI ĐẶT DTECH
    • PHIÊN BẢN ĐÓNG GÓI
    • PHIÊN BẢN CUSTOMIZE
      • UPDATE LẬP TRÌNH SANG KHÁCH HÀNG
    • CHUYỂN MÁY CHỦ ĐÓNG GÓI
    • LỖI KẾT NỐI MÁY CHỦ
    • LỖI ATTACH DATA KHÔNG NHẬN
    • QUẢN LÝ TRẠM
    • BẢN SERVICE
      • KHÔNG NHẬN ĐỦ DATA KHI ĐĂNG NHẬP
      • KHÔNG TẠO ĐƯỢC DATA MỚI
      • KIỂM TRA KHÓA BẢN DỊCH VỤ
    • LỖI ĐĂNG NHẬP TRÊN MÁY CHỦ
    • LỖI ĐĂNG NHẬP MÁY TRẠM
    • CÀI ĐẶT SQL LỖI
    • XỬ LÝ LIÊN QUAN KEY HỆ THỐNG
    • Lỗi đọc thông tin phần cứng (Alias not found)
    • A severe error occurred on the current command
    • GỬI HƯỚNG DẪN CÀI ĐẶT XONG
    • PHIÊN BẢN CŨ
  • HÓA ĐƠN ĐIỆN TỬ
    • CHỮ KÝ SỐ - CKS
    • CẤU HÌNH KẾT NỐI
    • CÔNG CỤ LIÊN QUAN
    • TỔNG HỢP LỖI CHUNG
      • Update trạng thái huỷ cho chứng từ
      • update trạng thái hoá đơn effect
      • Xoá menu chuột phải bị lặp lại
    • TỔNG HỢP LỖI M-INVOICE
    • TỔNG HỢP LỖI VNPT
    • TỔNG HỢP LỖI VIETTEL
    • TỔNG HỢP LỖI BKAV
    • TỔNG HỢP LỖI VIN
    • TỎNG HỢP LỖI EASYINVOICE
    • LƯU Ý HOÁ ĐƠN ĐIỆN TỬ
  • LỖI THƯỜNG GẶP
    • LƯU BÁO LỖI
    • GIAO DIỆN VỠ FONT
  • CONVERT DỮ LIỆU
    • EFFECT 2.0
    • EFFECT 3.0 - 4.0 - 6.0
    • MISA VERSION DESKTOP
    • 3T SOFT
  • EXCEL
  • DANH MỤC
    • TẠO CỘT MÃ TĂNG TỰ ĐỘNG
    • XOÁ BỎ CÁC DÒNG TRÙNG
    • UPDATE BANKACCOUNT THEO TÀI KHOẢN KẾ TOÁN
    • MỞ RỘNG KÝ TỰ CHO CỘT MÃ
    • XỬ LÝ SỐ LƯỢNG QUY ĐỔI
    • UPDATE CHITIETTHEO
  • DỮ LIỆU KẾ TOÁN
    • CẬP NHẬT DIỄN GIẢI BÁN HÀNG
  • LƯƠNG
    • CÁC LỖI THƯỜNG GẶP
  • NGHIỆP VỤ
    • TEMP NOTE PHÂN TÍCH
  • PHIẾU IN NHẬP LIỆU
    • IN MẪU DẠNG GROUP
    • Merger các ô của cột trên các dòng giống nhau
    • CÂU LỆNH FORMAT PHIẾU IN
    • Lặp lại tiêu đề in + logo... ở trang 2
    • Lặp lại tiêu đề in
  • KẾT NỐI HTKK
    • MAPING TỪ 1 BÁO CÁO
    • MAPING TỪ NHIỀU BÁO CÁO
  • BÁO CÁO
    • CÔNG THỨC
    • BÁO CÁO DYNAMIC ĐỘNG
      • dynamic cột là tháng
    • LẤY ĐIỀU KIỆN LỌC BÁO CÁO
    • TEMP NOTE PHÂN TÍCH
    • ENTER CHI TIẾT
    • Trước tất cả - chặn khi thiếu điều kiện lọc
  • EFFECT
    • TRUYỀN ĐẨY DỮ LIỆU *
    • GHÉP TỆP U*.DBF
    • KIỂM TRA TRẠM
    • FONT
    • BÁO CÁO
  • SQL SERVER
    • Một số lỗi truy vấn SQL
    • Tài khoản sa của SQL SERVER
    • SQL Server blocked access (OpenRowset/OpenDatasource)
    • Chế độ xp_cmd shell trong SQL Server
    • Tạo Backup tự động SQL Express
    • SQL Script Kiểm tra
    • SQL Scritp Fix Database
    • Attach and Detach Database
    • SQL LOCAL DB
    • HÀM TÁCH SỐ VÀ CHỮ KHỎI CHUỖI
    • KHÔNG TÌM THẤY SQL CONFIG
    • identity_insert table
    • BACKUP - RESTORE SQL
    • Insert tables
    • Sửa lỗi cài đặt SQL
    • Shrink Database
    • Kiểm tra port SQL sử dụng
    • CONVERT DATATYPE SQL
    • Xóa bản ghi trùng trên bảng
    • Replication SQL SERVER
  • THUẾ
    • HÓA ĐƠN MUA VÀO LÀ HÓA ĐƠN BÁN HÀNG CÓ CẦN KÊ KHAI TRÊN TỜ KHAI THUẾ GTGT KHÔNG?
    • Kết chuyển thuế GTGT cuối kỳ
  • LỆNH CẦN BIẾT
  • CÔNG CỤ KHÁC
    • RADMIN VPN
      • CÀI ĐẶT RADMIN
      • KIỂM TRA RADMIN
      • Sửa lỗi Bạn bị cấm ( You are banned )
      • Tắt Auto Metric Radmin VPN
      • Mô hình hoạt động của Radmin VPN
    • Tailscale VPN
  • Cài đặt Google Drive để backup dữ liệu
  • GIÁ THÀNH
    • NÔNG NGHIỆP - TRỒNG TRỌT
      • CÂY TRỒNG 1 LẦN, THU HOẠCH NHIỀU LẦN
      • CÂY TRỒNG LÂU NĂM
      • CÂY TRỒNG NGẮN NGÀY
  • 📶MẠNG LAN - INTERNET
  • KIẾN THỨC PHẦN CỨNG MÁY TÍNH
  • KIỂM TRA MÁY TÍNH
  • WINDOWS SERVER
    • WMI Repository
  • Chữ ký số
    • XOÁ DANH SÁCH CKS CŨ
  • Hướng dẫn tạo SSL/TLS miễn phí với OpenSSL và Let’s Encrypt
Powered by GitBook
On this page
  • 1. Attach Database ( Thêm database vào SQL SERVER)
  • 2. Detach Database ( Gỡ bỏ database khỏi SQL SERVER)
  • 3. ATTACH , DETACH NHIỀU DATABASES
  1. SQL SERVER

Attach and Detach Database

Những câu lệnh t-sql thêm và loại bỏ database MS SQL Server

1. Attach Database ( Thêm database vào SQL SERVER)

Chú ý cần phân quyền cho file .MDF và .LDF có quyền thì mới attach vào được, ví dụ Add Everyone vào 2 file này.

Lệnh 1: hay dùng

-- Khai báo các biến hệ thống
Declare @database_name nvarchar(100); -- Tên database
Declare @pathdb nvarchar(300);   -- Đường dẫn thư mục databsae
Declare @sql nvarchar(max)=N'';  -- Câu lệnh sql query
Declare @err_state int =0;  -- Trạng thái lỗi trả về

-- Điền thông tin attach db vào:

set @database_name=N'DTECH_HN';   --Tên database cần Attach vào

set @pathdb=N'D:\DATA'   -- Đường dẫn thư mục chứa databse và log cần Attach vào

-- Thực thi câu lệnh
set @sql=@sql+'EXEC sp_attach_db @dbname = N'''+@database_name+''',
              @filename1 = N'''+@pathdb+'\'+@database_name+'.mdf'', 
              @filename2 =N'''+@pathdb+'\'+ @database_name +'_log.ldf'''
BEGIN TRY
    print @sql
	exec(@sql)
END TRY
BEGIN CATCH
    SELECT @err_state = ERROR_STATE()
END CATCH;

------------------------------------------------------------------------------------------------
if @err_state=3  -- Đã tồn tại Database cần attach vào rồi, thông báo, ko làm gì nữa
BEGIN
	Print N'Đã tồn tại database ['+@database_name+'] trên SQL SERVER.'
END
------------------------------------------------------------------------------------------------
if @err_state=101 -- Thực hiện câu lệnh Attach lại khi file mdf không có _LOG trong tên file
BEGIN
	-- Thực thi câu lệnh
	set @sql='EXEC sp_attach_db @dbname = N'''+@database_name+''',
				  @filename1 = N'''+@pathdb+'\'+@database_name+'.mdf'', 
				  @filename2 =N'''+@pathdb+'\'+ @database_name +'.ldf'''
	print @sql
	exec(@sql)
END
-- Thay giá trị ở biến @dbname, đường dẫn tới file mdf, ldf
EXEC sp_attach_db @dbname = N'Dtech2022_DEMO',   
    @filename1 =   
N'D:\DTECH\DTECHDEMO_MAY\DataSQL\Dtech2022_DEMO.mdf',   
    @filename2 =   
N'D:\DTECH\DTECHDEMO_MAY\DataSQL\Dtech2022_DEMO_log.ldf'; 

Lệnh 2:

-- Attach khôi phục lại file log
USE [master]
GO
CREATE DATABASE [TestDB] ON 
( FILENAME = N'E:\MSSQL\TestDBCopy.mdf' )
 FOR ATTACH_REBUILD_LOG 
GO

-- Attach khôi phục lại ép buộc tạo được file log
USE master;

CREATE DATABASE [TestDB]
    ON  ( FILENAME = N'E:\MSSQL\TestDB_1.mdf' )
    FOR ATTACH_FORCE_REBUILD_LOG;
GO

Lệnh 3:

-- Attach thêm database với tuỳ chọn
USE [master]
GO

CREATE DATABASE [TestDB_Repair]
 CONTAINMENT = NONE
 ON  PRIMARY 
( NAME = N'TestDB_Repair_file1', 
			FILENAME = N'E:\MSSQL\TestDB_Repair_1.mdf',
			SIZE = 8MB , 
			MAXSIZE = UNLIMITED, 
			FILEGROWTH = 64MB) 
 LOG ON 
( NAME = N'TestDB_Repair_log_file1',
			 FILENAME = N'E:\MSSQL\TestDB_Repair_1.ldf',
			 SIZE = 8MB,
			 MAXSIZE = 2048GB,
			 FILEGROWTH = 32MB)
GO

2. Detach Database ( Gỡ bỏ database khỏi SQL SERVER)

Lệnh 1: hay dùng

-- Thay Dbname bằng tên database cần gỡ bỏ
EXEC sp_detach_db 'Dbname', 'true'; 

Lệnh 2: gỡ bỏ bỏ qua bước kiểm tra

USE [master]
GO
ALTER DATABASE [SQLShack] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
USE [master]
GO
EXEC master.dbo.sp_detach_db @dbname = N'SQLShack', @skipchecks = 'false'
GO

3. ATTACH , DETACH NHIỀU DATABASES

  1. ATTACH NHIỀU DATABASE

  • Cách 1: Thêm 1 Proc mới trên SQL và chạy lệnh gọi Proc đó với đường dẫn:

--Bước 1. Thêm Proc usp_MultiAttachSingleMDFFiles  ở phía dưới vào trước
--Bước 2. Sửa dụng Proc usp_MultiAttachSingleMDFFiles để chạy trên SQL Query:
-- Chú ý: C:\DTECH\DataSQL là đường dẫn thư mục chứa file .mdf và .ldf
-- Trước khi chạy thì cần chuyển file log .Ldf sang một thư mục khác hoặc xoá file log đi chỉ để file data .mdf để thực hiện
USE master
GO
EXEC dbo.usp_MultiAttachSingleMDFFiles 'C:\DTECH\DataSQL'   
GO 


---Proc usp_MultiAttachSingleMDFFiles cần thêm ở bước 1
USE master
GO
CREATE PROCEDURE [dbo].[usp_MultiAttachSingleMDFFiles] ( @mdfTempDir nvarchar(500) )
AS
BEGIN  
   DECLARE @dirstmt       nvarchar(1000)
   DECLARE @currFile      nvarchar(160)
   DECLARE @db_name       nvarchar(256)
   DECLARE @phys_name     nvarchar(520)
   DECLARE @dbccstmt      nvarchar(1000)
   DECLARE @db2attch_ver  INT
   DECLARE @curr_srv_ver  INT  
   DECLARE @mdfFileNames  TABLE (mdfFile nvarchar(260))
   DECLARE @mdfFileATTR   TABLE (attrName sql_variant, attrValue sql_variant)
   
   DECLARE cf CURSOR FOR SELECT mdfFile FROM @mdfFileNames

   SET NOCOUNT ON

   -- get all mdf file names only , in bare format.
   SET @dirstmt = 'dir /b "' + @mdfTempDir + '"\*.mdf'

   INSERT into @mdfFileNames 
   EXEC xp_cmdshell @dirstmt
   
   DELETE from @mdfFileNames where mdfFile IS NULL or mdfFile = 'File Not Found'

   -- if file is already attached skip it
   DELETE FROM @mdfFileNames 
   WHERE mdfFile IN (SELECT mdfFile FROM @mdfFileNames a INNER JOIN sys.master_files b ON lower(@mdfTempDir + '\' + a.mdfFile) = lower(b.physical_name) )

   -- if no files exist then exit process
   IF not exists (SELECT TOP 1 * FROM @mdfFileNames)
   BEGIN
      PRINT 'No files found to process'
      RETURN
   END

   -- get the current server database version
   SELECT  @curr_srv_ver = CONVERT (int,DATABASEPROPERTYEX('master', 'version'))

   BEGIN TRY

      OPEN cf

      FETCH NEXT FROM cf INTO @currFile

      WHILE @@FETCH_STATUS = 0 
      BEGIN 
 
         SET @phys_name =  @mdfTempDir + '\' + @currFile
         SET @dbccstmt = 'DBCC checkprimaryfile (' + '"' + @phys_name + '"' + ',2)'

         INSERT INTO @mdfFileATTR 
         EXEC (@dbccstmt)
         
         SELECT @db_name = convert (nvarchar(256), attrValue)
         FROM @mdfFileATTR
         WHERE attrName = 'Database name'
      
         -- get the candidate to be attached db version
         SELECT @db2attch_ver = convert (int, attrValue)
         FROM @mdfFileATTR
         WHERE attrName = 'Database version'

         -- if the current server database version is less that the attached db version 
         -- OR
         -- if the database already exists then skip the attach 
         -- print an appropriate message message
         IF (@db2attch_ver > @curr_srv_ver)
            OR
            (exists (SELECT 1 
                     FROM sys.databases d 
                     WHERE RTRIM(LTRIM(lower(d.name))) = RTRIM(LTRIM(lower(@db_name)))))
         BEGIN 
            PRINT ''
            PRINT ' Attach for database ' + @db_name + ' was not performed! '
            PRINT ' Possible reasons : ' 
            PRINT '1. ' +  @db_name + ' DB version is higher that the currnet server version.'
            PRINT '2. ' +  @db_name + ' DB already exists on server.'
            PRINT ''
         END 
         ELSE 
         BEGIN 
            EXEC sp_attach_single_file_db @dbname= @db_name , @physname = @phys_name
            PRINT ''
            PRINT 'Database "' + @db_name + '" attached to server OK using file ' + @currFile + '".'
            PRINT ''
            DELETE FROM @mdfFileATTR
         END 

         FETCH NEXT FROM cf INTO @currFile

      END 
    
      CLOSE cf
      DEALLOCATE cf
   END TRY
   BEGIN CATCH
      PRINT 'Error while attaching FILE ' + @phys_name + ',...Exiting procedure'
      CLOSE cf
      DEALLOCATE cf
   END CATCH 

   SET NOCOUNT OFF
END 
GO
  • Cách 2:

DECLARE @DataPath VARCHAR(MAX) = 'Data file path'
DECLARE @LogPath VARCHAR(MAX) = 'Log file path'
 
IF (OBJECT_ID('tempdb.dbo.#DataFiles') IS NOT NULL)
DROP TABLE #DataFiles
CREATE TABLE #DataFiles
(mdf VARCHAR(400))
 
IF (OBJECT_ID('tempdb.dbo.#DBFiles') IS NOT NULL)
DROP TABLE #DBFiles
CREATE TABLE #DBFiles
(status INT,
fileid INT,
name VARCHAR(256),
filename VARCHAR(256))
 
IF (OBJECT_ID('tempdb.dbo.#DBProperties') IS NOT NULL)
DROP TABLE #DBProperties
CREATE TABLE #DBProperties
(property VARCHAR(256),
value SQL_VARIANT)
 
DECLARE @Cmd VARCHAR(4000)
DECLARE @DataFileNames  TABLE (mdfFile nvarchar(260))
DECLARE @DataFileName VARCHAR(256)
DECLARE @ndfFileName VARCHAR(256)
DECLARE @AttachCMD VARCHAR(2000)
 
--get list of .mdf files from data directory
SET @Cmd = 'dir /b "' + @DataPath + '"\*.mdf'
 
INSERT into #DataFiles 
EXEC xp_cmdshell @Cmd
 
--cursor containing only .mdf files are aren't associatated with an existing database
UPDATE #DataFiles
SET mdf = @DataPath + '\' + mdf
DECLARE DataFilesCur CURSOR STATIC FORWARD_ONLY FOR
    SELECT mdf
    FROM #DataFiles
    WHERE mdf != 'null'
    AND mdf NOT IN (SELECT physical_name FROM sys.master_files)
 
OPEN DataFilesCur
 
FETCH NEXT FROM DataFilesCur INTO @DataFileName
 
WHILE @@FETCH_STATUS = 0
BEGIN
    TRUNCATE TABLE #DBFiles
    TRUNCATE TABLE #DBProperties
 
    --DBCC CHECKPRIMARYFILES to return all files associated with the database
    INSERT INTO #DBFiles(status, fileid, name, filename)
    EXEC ('DBCC CHECKPRIMARYFILE(''' + @DataFileName + ''', 3) WITH NO_INFOMSGS')
 
    --DBCC CHECKPRIMARYFILES to get database name
    INSERT INTO #DBProperties (property, value)
    EXEC ('DBCC CHECKPRIMARYFILE(''' + @DataFileName + ''', 2) WITH NO_INFOMSGS')
 
    --Begin constructing file attachment command
    SELECT @AttachCMD =  'CREATE DATABASE ' + QUOTENAME(CAST(value AS SYSNAME))
    FROM #DBProperties
    WHERE property = 'Database name'
 
    SET @AttachCMD = @AttachCMD + ' ON (FILENAME = ''' + @DataFileName + '''),'
 
    SELECT @AttachCMD = @AttachCMD + '(FILENAME = ''' + @LogPath + '\' + REVERSE(SUBSTRING(REVERSE(RTRIM(filename)),0,CHARINDEX('\',REVERSE(RTRIM(filename))))) + ''')'
    FROM #DBFiles
    WHERE filename LIKE '%.ldf'
 
    --cursor through the .ndf files
    DECLARE CURSOR ndfFileCur STATIC FORWARD_ONLY FOR
        SELECT filename
        FROM #DBFiles
        WHERE filename LIKE '%.ndf'
 
    OPEN ndfFileCur
    FETCH NEXT FROM ndfFileCur INTO @ndfFileName
 
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @AttchCMD = @AttachCMD + ',(FILENAME = ''' + @DataPath + '\' + REVERSE(SUBSTRING(REVERSE(RTRIM(@ndfFileName)),0,CHARINDEX('\',REVERSE(RTRIM(@ndfFileName))))) + ''')'
        FETCH NEXT FROM ndfFileCur INTO @ndfFileName
    END
 
    CLOSE ndfFileCur
    DEALLOCATE ndfFileCur
 
    SET @AttachCMD = @AttachCMD + ' FOR ATTACH'
 
    --PRINT @AttachCMD
    EXEC (@AttachCMD)
    FETCH NEXT FROM DataFilesCur INTO @DataFileName
END
 
CLOSE DataFilesCur
DEALLOCATE DataFilesCur
  1. DETACH NHIỀU DATABASE

  • Cách 1:

DECLARE @dbName varchar(255); --Biến lưu trữ các database name
DECLARE DBCURSOR CURSOR FOR
    SELECT name
    FROM sys.databases 
    WHERE len(owner_sid)>1; -- All user databases
 
OPEN DBCURSOR
FETCH Next from DBCURSOR INTO @dbName
WHILE @@FETCH_STATUS = 0 
BEGIN
    PRINT 'EXEC sp_detach_db ' + @dbName + CHAR(10) -- CHAR(10) for newline 
    + 'GO' + CHAR(10) 
    + 'Print ''Detach of ' + @dbName + ' database completed successfully'''
    + CHAR(10) + 'GO'
    FETCH NEXT FROM DBCURSOR INTO @dbName
END
 
CLOSE DBCURSOR    
DEALLOCATE DBCURSOR

Cách 2:

WITH Targets
AS (
    SELECT
      dbid,
      DB_NAME(dbid) db_name,
      fileid,
      filename
    FROM master.dbo.sysaltfiles
    WHERE dbid > 4
      AND DATABASEPROPERTYEX(DB_NAME(dbid), 'Status') = 'ONLINE'
   )
SELECT
  db_name,
  'exec sp_detach_db @dbname = N''' + db_name + ''';' Detach,
  'exec sp_attach_db @dbname = N''' + db_name + '''' + (SELECT
    ', @filename' + CAST(fileid AS varchar) + '=N''' + filename + ''''
  FROM Targets f
  WHERE f.dbid = d.dbid
  FOR xml PATH (''))
  + ';' AS Attach
FROM (SELECT DISTINCT dbid, db_name FROM Targets) d

--Copy câu lệnh ra để lấy lệnh thực thi

Cách 3: Áp dụng truyền thêm tham số 1 hoặc 0 để xác định Detach hoặc Attach

USE [master];
GO
DECLARE @database NVARCHAR(200) ,
    @cmd NVARCHAR(1000) ,
    @detach_cmd NVARCHAR(4000) ,
    @attach_cmd NVARCHAR(4000) ,
    @file NVARCHAR(1000) ,
    @i INT ,
    @DetachOrAttach BIT;

SET @DetachOrAttach = 1;

-- 1 Detach 0 - Attach
-- 1 Generates Detach Script
-- 0 Generates Attach Script
DECLARE dbname_cur CURSOR STATIC LOCAL FORWARD_ONLY
FOR
    SELECT  RTRIM(LTRIM([name]))
    FROM    sys.databases
    WHERE   database_id > 4;
 -- No system databases
OPEN dbname_cur

FETCH NEXT FROM dbname_cur INTO @database

WHILE @@FETCH_STATUS = 0 
    BEGIN
        SELECT  @i = 1;

        SET @attach_cmd = '-- ' + QUOTENAME(@database) + CHAR(10)
            + 'EXEC sp_attach_db @dbname = ''' + @database + '''' + CHAR(10);
      -- Change skip checks to false if you want to update statistics before you detach.
        SET @detach_cmd = '-- ' + QUOTENAME(@database) + CHAR(10)
            + 'EXEC sp_detach_db @dbname = ''' + @database
            + ''' , @skipchecks = ''true'';' + CHAR(10);

      -- Get a list of files for the database
        DECLARE dbfiles_cur CURSOR STATIC LOCAL FORWARD_ONLY
        FOR
            SELECT  physical_name
            FROM    sys.master_files
            WHERE   database_id = DB_ID(@database)
            ORDER BY [file_id];

        OPEN dbfiles_cur

        FETCH NEXT FROM dbfiles_cur INTO @file

        WHILE @@FETCH_STATUS = 0 
            BEGIN
                SET @attach_cmd = @attach_cmd + '    ,@filename'
                    + CAST(@i AS NVARCHAR(10)) + ' = ''' + @file + ''''
                    + CHAR(10);
                SET @i = @i + 1;

                FETCH NEXT FROM dbfiles_cur INTO @file
            END

        CLOSE dbfiles_cur;

        DEALLOCATE dbfiles_cur;

        IF ( @DetachOrAttach = 0 ) 
            BEGIN
            -- Output attach script
                PRINT @attach_cmd;
            END
        ELSE -- Output detach script
            PRINT @detach_cmd;

        FETCH NEXT FROM dbname_cur INTO @database
    END

CLOSE dbname_cur;

DEALLOCATE dbname_cur;
PreviousSQL Scritp Fix DatabaseNextSQL LOCAL DB

Last updated 11 months ago