খালি টেবিলগুলির জন্য কীভাবে একটি ডাটাবেসকে জিজ্ঞাসা করবেন


28

কিছু 'বিকাশকারী'র কারণে আমরা আমাদের সিস্টেমে কাজ করে যাচ্ছি খালি টেবিল নিয়ে আমাদের সমস্যা হয়েছে। আমরা দেখতে পেয়েছি মেঘে স্থানান্তরকালে বেশ কয়েকটি টেবিল অনুলিপি করা হয়েছিল, তবে সেগুলির ডেটা ছিল না।

আমি ব্যবহারকারীর টেবিলগুলি খালি আছে তা সন্ধান করতে সিস্টেম টেবিলগুলি একটি ক্যোয়ারী চালাতে চাই। আমরা এমএস এসকিউএল 2008 আর 2 ব্যবহার করছি।

সাহায্যের জন্য ধন্যবাদ.

উত্তর:


46

উত্তোলন sys.tablesএবং sys.partitions:

select
    t.name table_name,
    s.name schema_name,
    sum(p.rows) total_rows
from
    sys.tables t
    join sys.schemas s on (t.schema_id = s.schema_id)
    join sys.partitions p on (t.object_id = p.object_id)
where p.index_id in (0,1)
group by t.name,s.name
having sum(p.rows) = 0;

পার্টিশনযুক্ত টেবিলগুলির সাথে আপনার বিভ্রান্তি না রয়েছে তা নিশ্চিত করতে সারিগুলির একটি যোগফল ব্যবহার করুন। 0 বা 1 এর সূচি_আইডি এর অর্থ আপনি কেবল নিজের গাদা বা ক্লাস্টারযুক্ত সূচকগুলির জন্য সারি গণনাটি দেখছেন।


9

যেমনটি মাইক ফাল এবং কিন উভয়ই উল্লেখ করেছেন, সিস্টেম টেবিলগুলি আপনার বন্ধু।

আরও কোড-সম্পূর্ণ সংস্করণের জন্য, আমি নিম্নলিখিতগুলি নিয়ে এসেছি, যা আপনাকে আপনার ডাটাবেজে প্রতিটি টেবিলে ব্যবহৃত মোট ডেটা স্পেস দেখতে দেয়।

USE master;

CREATE DATABASE TestDB;
GO

USE tempdb;
ALTER DATABASE TestDB SET RECOVERY SIMPLE;
GO

USE TestDB;
CREATE TABLE Test1 (
    Test1ID INT NOT NULL PRIMARY KEY IDENTITY(1,1)
    , TestData nvarchar(255) CONSTRAINT DF_Test1_TestData DEFAULT (NEWID())
);

GO

TRUNCATE TABLE Test1;

SELECT s.name + '.' + t.name AS TableName,
    sum(p.rows) AS TotalRows,
    SUM(au.data_pages) AS DataPagesUsed
FROM sys.tables t
    INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
    INNER JOIN sys.partitions p ON t.object_id = p.object_id
    INNER JOIN sys.allocation_units au ON p.hobt_id = au.container_id
WHERE au.type = 1 or au.type = 3 
    AND t.is_ms_shipped = 0
GROUP BY s.name, t.name
    ORDER BY SUM(au.data_pages) DESC;

INSERT INTO Test1 DEFAULT VALUES;

SELECT s.name + '.' + t.name AS TableName,
    sum(p.rows) AS TotalRows,
    SUM(au.data_pages) AS DataPagesUsed
FROM sys.tables t
    INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
    INNER JOIN sys.partitions p ON t.object_id = p.object_id
    INNER JOIN sys.allocation_units au ON p.hobt_id = au.container_id
WHERE au.type = 1 or au.type = 3 
    AND t.is_ms_shipped = 0
GROUP BY s.name, t.name
    ORDER BY SUM(au.data_pages) DESC;

শেষ 3 বিবৃতি ফলাফল:

এখানে চিত্র বর্ণনা লিখুন


6

এখানে পাওয়ারশেল সংস্করণ রয়েছে:

এসকিউএল সার্ভার ম্যানেজমেন্ট অবজেক্টস (এসএমও) ব্যবহার করে


function Find-EmptyTables ($server,$database) 
{

    # Load SMO assembly
    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | Out-Null

    $s = New-Object 'Microsoft.SqlServer.Management.Smo.Server' $server
    $db = $s.Databases.Item($database)
    $db.Tables | Where-Object { $_.RowCount -eq 0 } | Select Schema, Name, RowCount
}

ডাটাবেসের সংখ্যার উপর নির্ভর করে আপনি কোনও ভেরিয়েবলের পপুলেটেড প্রতিটি ডাটাবেস নামের তালিকার বিপরীতে উপরের ফাংশনটি ব্যবহার করতে পারেন এবং একটি সার্ভারের সাথে ডিল করে যদি একই সময়ে এটি আউটপুট পান:


$DBList = 'MyDatabase1','MyDatabase2'

foreach ($d in $DBList) {
Find-EmptyTables -server MyServer -database $d | 
  Select @{Label="Database";Expression={$d}}, Schema, Name, RowCount
}

4

এখানে অন্যান্য প্রতিক্রিয়া দুর্দান্ত তবে সম্পূর্ণতার জন্য: এসকিউএল সার্ভার ম্যানেজমেন্ট স্টুডিও> ডিব্লিক ক্লিক করুন ডিবি> রিপোর্টস> স্ট্যান্ডার্ড রিপোর্টস> টেবিলের সাহায্যে ডিস্ক ব্যবহার


এটি কেবল খালি খালি নয়, সমস্ত টেবিলগুলি ফিরিয়ে আনবে। আমি বিশ্বাস করি না যে আপনি এই রিপোর্টগুলিতে ফিল্টার প্রয়োগ করতে পারেন।
শন মেল্টন

ঐটা সত্য. প্যাড প্যাড প্যাড
onupdatecascade

তবে এটি একটি খুব ভাল উত্তর। আগের চেয়ে সহজ মাত্র 2 ক্লিকের দূরত্বে।
মেরিয়ান

তবে, আপনি রেকর্ড সংখ্যার দ্বারা তালিকাটি অর্ডার করতে পারেন
রবার্ট মাইকস

1

আমি সাধারণত একটি ক্যোয়ারী তৈরি করি যা আমার যে ক্যোয়ারী তৈরি করে তা তৈরি করে এবং তারপরে সেই ম্যানুয়ালি সম্পাদন করি, তবে আপনি যদি এটি চান তবে একসাথে ...

declare @sql nvarchar(max) ;

set @sql = ';with cte as (' + (select  
        ( 
            SELECT case when row_number() 
                 over (order by table_schema, table_name) = 1 then '       ' 
                   else ' union ' end + 
                'select count(*) rws, ''[' +
                      t.TABLE_SCHEMA +'].[' + t.table_name + 
                ']'' tbl from ' + '['+ 
                      t.TABLE_SCHEMA + '].[' + TABLE_NAME + ']' + 
                CHAR(10) AS [data()] 
            FROM INFORMATION_SCHEMA.TABLES t
            FOR XML PATH ('') 
        )) + ') select * from cte where rws = 0;'

execute sp_executesql @sql;

1

অতিরিক্ত উত্তর হিসাবে, Undocumented সিস্টেম সঞ্চিত পদ্ধতি sp_MSforeachtableএখানে দরকারী।

CREATE TABLE #CountRows ( TableName nvarchar(260), NumRows int) ;
GO
EXEC sp_MSforeachtable 'insert into #CountRows select ''?'', count(*) from ?' ;
SELECT * FROM #CountRows WHERE NumRows = 0 ORDER BY TableName ;
DROP TABLE #CountRows ;

অননুমোদিত বৈশিষ্ট্যগুলি সম্পর্কে সাধারণ সতর্কতাগুলি প্রযোজ্য।

আপনি যদি কৌতূহলী হন বা আপনি যদি নিশ্চিত হতে চান তবে এটির কোনও খারাপ অভ্যাস নেই master এটি একটি কার্সার তৈরি করতে গতিশীল এসকিউএল ব্যবহার করে, যা কার্য সম্পাদনের জন্য খারাপ (কার্সার = ধীর!), সুতরাং কেবলমাত্র একটি প্রক্রিয়াটির জন্য এই পদ্ধতিটি ব্যবহার করুন।

অতিরিক্তভাবে, sp_MSforeachtableঅ্যাজুরে ডেটাবেস পাওয়া যায় না।


1
DECLARE @toCheck INT;
DECLARE @countoftables INT;
DECLARE @Qry NVARCHAR(100);
DECLARE @name VARCHAR(100);
BEGIN
    IF object_id('TEMPDB.DBO.#temp') IS NOT NULL drop table #temp;
    SELECT ROW_NUMBER() OVER(ORDER BY name) AS ROW,CountStatement = 'SELECT @toCheck = COUNT(*) FROM  ' + name,name INTO #temp FROM SYS.TABLES  WITH (NOLOCK)
    --SELECT * FROM #temp  ORDER BY ROW
    SET @countoftables  =(SELECT COUNT(*) FROM #temp)
    WHILE (@countoftables > 0)
        BEGIN
            SET @Qry =  (SELECT CountStatement FROM #temp  WITH (NOLOCK) WHERE ROW = @countoftables);
            SET @name = (SELECT name FROM #temp  WITH (NOLOCK) WHERE ROW = @countoftables);
            EXEC SP_EXECUTESQL @qry,N'@toCheck INT OUTPUT',@toCheck OUTPUT;
            IF(@toCheck=0)
                BEGIN
                    PRINT 'Table: ' + @name + ', count: ' +  convert(varchar(10),@toCheck);
                END
            --ELSE
            --  BEGIN
            --      PRINT 'Table: ' + @name + ', count: ' +  convert(varchar(10),@toCheck);
            --  END
            SET  @countoftables = @countoftables -1;            
        END
END

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.