مطالب
تعیین اعتبار کردن یک عبارت SQL - قسمت دوم

مطلبی را روز قبل نوشتم در مورد تعیین اعتبار یک کوئری. این مورد از آنجایی حائز اهمیت می‌شود که برای مثال تغییری در ساختار یکی از جداول حاصل شود. اکنون می‌خواهیم بررسی کنیم آیا سیستم از کار افتاده یا نه!؟
شما می‌توانید نام یک فیلد را تغییر دهید (حتی اگر این فیلد در یک رویه ذخیره شده استفاده شده باشد) و هیچ خطایی هم نخواهید گرفت و این منشاء دردسرهای زیادی خواهد بود.
در حالت استفاده از SET NOEXEC ON ، کوئری مورد نظر فقط کامپایل می‌شود و همچنین از لحاظ نحوی بررسی خواهد شد، اما این کافی نیست.
مثال زیر را در نظر بگیرید:

Create PROCEDURE Test1
AS
SELECT * FROM tblPIDs1
جدول tblPIDs1 در دیتابیس مورد نظر وجود ندارد.
این کوئری قابل اجرا است. دکمه‌ی F5 را فشار دهید، بلافاصله رویه ذخیره شده‌ی Test1 برای شما ایجاد خواهد شد.
سپس کوئری زیر را اجرا کنید:

USE testdb
SET NOEXEC ON;
exec test1 ;
SET NOEXEC OFF;
بدون مشکل و بروز خطایی، پیغام زیر را نشان می‌دهد:
Command(s) completed successfully

ایرادی هم وارد نیست چون فقط عملیات parsing و compile صورت گرفته و نه اجرای واقعی رویه ذخیره شده. اینجا از لحاظ دستوری مشکلی وجود ندارد.

در این نوع موارد می‌توان از SET FMTONLY ON استفاده کرد. این مورد اجرای غیر واقعی یک کوئری را سبب می‌شود (تاثیری روی دیتابیس موجود نخواهد داشت، برای مثال اگر در رویه ذخیره شما عبارت insert وجود داشت، دیتایی insert نخواهد شد) و تنها متادیتای حاصل را بازگشت می‌دهد. مثلا نام ستون‌های یک کوئری را و همچنین در این حین اگر خطایی رخ داده باشد، آن‌را نیز ارائه خواهد داد.

USE testdb
SET FMTONLY ON;
exec test1 ;
SET FMTONLY OFF;
با اجرای کوئری فوق خطای زیر ظاهر می‌شود:
Msg 208, Level 16, State 1, Procedure test1, Line 3
Invalid object name 'tblPIDs1'.
برای اتوماسیون این توانایی می‌توان از کوئری زیر استفاده کرد:

USE testdb;

SET NOCOUNT ON;

DECLARE @name NVARCHAR(MAX),
@sql NVARCHAR(MAX),
@type CHAR(2), -- object type
@type_desc NVARCHAR(60), -- object type description
@params NVARCHAR(MAX) -- parameters

DECLARE @tblInvalid TABLE (
-- invalid objects
[type_desc] NVARCHAR(60),
[name] NVARCHAR(MAX),
[error_number] INT,
[error_message] NVARCHAR(MAX),
[type] CHAR(2)
);

DECLARE testSPs CURSOR FAST_FORWARD
FOR
SELECT [name] = OBJECT_NAME(SM.[object_id]),
[type] = SO.[type],
SO.[type_desc],
[params] = (
SELECT (
SELECT CONVERT(
XML,
(
SELECT STUFF(
(
SELECT ', ' + [name] +
'=NULL' AS
[text()]
FROM sys.parameters
WHERE [object_id] = SM.[object_id]
FOR XML PATH('')
),
1,
1,
''
)
)
)
FOR XML RAW,
TYPE
).value('/row[1]', 'varchar(max)')
)
FROM sys.sql_modules SM
JOIN sys.objects SO
ON SO.[object_id] = SM.[object_id]
WHERE SO.[is_ms_shipped] = 0
AND SO.[type] = 'P'


OPEN testSPs
FETCH NEXT FROM testSPs INTO @name, @type, @type_desc, @params

WHILE (@@FETCH_STATUS = 0)
BEGIN
BEGIN TRY
SET @sql = 'SET FMTONLY ON; exec ' + @name + ' ' + @params +
'; SET FMTONLY OFF;'
--PRINT @sql;
EXEC (@sql) ;
END TRY
BEGIN CATCH
PRINT @type_desc + ', ' + @name + ', Error: ' + CAST(ERROR_NUMBER() AS VARCHAR)
+ ', ' + ERROR_MESSAGE();
INSERT INTO @tblInvalid
SELECT @type_desc,
@name,
ERROR_NUMBER(),
ERROR_MESSAGE(),
@type

;
END CATCH


FETCH NEXT FROM testSPs INTO @name, @type, @type_desc, @params
END
CLOSE testSPs
DEALLOCATE testSPs


SELECT [type_desc],
[name],
[error_number],
[error_message]
FROM @tblInvalid
ORDER BY
CHARINDEX([type], ' U V PK UQ F TR FN TF P SQ '),
[name];

توضیحات:
این کوئری، در دیتابیس جاری که در قسمت use dbname مشخص می‌شود، تمامی رویه‌های ذخیره شده را به صورت خودکار پیدا می‌کند. سپس لیست آرگومان‌های آن‌ها را نیز یافته و عبارت exec مربوطه را تشکیل می‌دهد. سپس با استفاده از SET FMTONLY ON سعی در شبیه سازی اجرای تک تک رویه‌های ذخیره شده می‌کند. اگر خطایی در این بین رخ داد، آن‌ها را در یک جدول موقتی ذخیره کرده و در آخر نتیجه را نمایش می‌دهد.

ارزش این کوئری زمانی مشخص می‌شود که تعداد زیادی رویه ذخیره شده داشته باشید اما نمی‌دانید کدامیک از آن‌ها بر اساس آخرین تغییرات صورت گرفته، هنوز معتبر هستند یا نه. آیا به قول معروف، سیستم اومد پایین یا خیر!؟

نکته:
قسمتی که از XML استفاده شده جهت concatenating نتیجه حاصل از کوئری، مورد استفاده قرار گرفته و این روزها بحث رایجی است که در بسیاری از سایت‌ها در مورد آن می‌توان مطالب مفیدی را یافت. راه دیگر انجام آن استفاده از COALESCE می‌باشد.


مآخذ:
Check Validity of SQL Server Stored Procedures
Which of your Stored Procedures are no longer Valid
SET FMTONLY ON

اشتراک‌ها
با DotVVM، برنامه‌های ASP.NET Web Forms خود را بر فراز NET Core. اجرا کنید!

Did you know that DotVVM can be used to incrementally modernize old ASP.NET Web Forms applications and lift them to .NET Core? It is much easier than doing a full rewrite, and the application can be deployed at any time during the entire process.

  • Install DotVVM NuGet package in your Web Forms site
  • Create a DotVVM master page using the same CSS
  • Start converting ASPX pages to DotHTML syntax, one at a time
  • When all the Web Forms pages are gone, change your CSPROJ to use .NET Core 
با DotVVM، برنامه‌های ASP.NET Web Forms خود را بر فراز NET Core. اجرا کنید!
مطالب
زیر نویس فارسی ویدیوهای ساخت برنامه‌های مترو توسط سی شارپ و XAML - قسمت سوم

زیرنویس‌های فارسی قسمت سوم «Building Windows 8 Metro Apps in C# and XAML» را از اینجا و یا اینجا می‌تونید دریافت کنید.

لیست سرفصل‌های قسمت سوم به شرح زیر است:

Controls  00:48:08 
WinRT provides numerous XAML controls, which act as the building blocks of your applications.
Some of these will be familiar, while some are new to Metro.
Introduction
Command Controls
Demo: Application Bar
Context Menus
Demo: Context Menus
Application Settings
CheckBox, RadioButton, and ToggleSwitch
Progress Controls
Demo: Progress Controls
Displaying Text
Demo: Displaying Text
Text Entry
Sliders
Styling
WebView
UserControl
Summary

مطالبی که بیشتر در این سری بر روی آن‌ها تمرکز شده، مباحث صفحات لمسی و تغییرات کنترل‌های ویندوز 8 جهت سازگاری با این مساله است. بنابراین در این سری بیشتر از هرچیزی finger ، tap و touch را خواهید شنید. جایی که چند جا را می‌شود همزمان لمس کرد و با چندین انگشت همزمان کار کرد که نکات قابل توجهی را نسبت به دنیای تک بعدی ماوس به همراه دارد.

نظرات مطالب
فعالسازی امکانات Refactoring افزونه‌ی Roslynator در VSCode
به روز رسانی
در این تاریخ، تنها کافی است افزونه‌ی Roslynator مخصوص VSCode را نصب کنید (صرفنظر از تمام مطالب این صفحه). سپس به مسیر زیر مراجعه کرده:
%USERPROFILE%\.omnisharp
و به فایل omnisharp.json موجود در آن، تنظیم timeout و سایر تنظیمات زیر را اضافه کنید:
{
    "RoslynExtensionsOptions": {
        "enableDecompilationSupport": true,
        "enableAnalyzersSupport": true,
        "enableImportCompletion": true,
        "enableAsyncCompletion": true,
        "documentAnalysisTimeoutMs": 600000,
        "LocationPaths": [
            "c:/Users/Vahid/.vscode/extensions/josefpihrt-vscode.roslynator-3.2.2/roslyn/common",
            "c:/Users/Vahid/.vscode/extensions/josefpihrt-vscode.roslynator-3.2.2/roslyn/analyzers",
            "c:/Users/Vahid/.vscode/extensions/josefpihrt-vscode.roslynator-3.2.2/roslyn/refactorings",
            "c:/Users/Vahid/.vscode/extensions/josefpihrt-vscode.roslynator-3.2.2/roslyn/fixes"
        ]
    }
}
timeout پیش‌فرض آن 10 ثانیه است که رقم کوچکی است.
اشتراک‌ها
بی‌جهت لینوکسی‌ها را بخاطر باگ bash شرمنده نکنید

This is a defense of the most prolific and dedicated public servant that has graced the world in my lifetime. One man has added hundreds of billions, if not trillions of dollars of value to the global economy. This man has worked tirelessly for the benefit of everyone around him. It is impossible to name a publicly traded company that has not somehow benefited from his contributions, and many have benefited to the tune of billions. In return for the countless billions of wealth that people made from the fruits of his labor, he was rewarded with poverty and ridicule. Now that the world is done taking from him, they are heading to the next step of vilifying him as incompetent.

بی‌جهت لینوکسی‌ها را بخاطر باگ bash شرمنده نکنید
نظرات مطالب
نحوه ایجاد یک تصویر امنیتی (Captcha) با حروف فارسی در ASP.Net MVC
ممنون بابت راهنماییتون؛ روش‌های قبلی مشکل من رو حل نکردن چرا؟ فقط توضیحات شما مشکلمو حل کرد. ولی تفاوت اینکه identity من الان روی network service با قبلش که روی app pool بوده چه فرقی داره؟ یعنی مشکل امنیتی ایجاد نمیکنه؟
نظرات مطالب
نحوه ایجاد یک تصویر امنیتی (Captcha) با حروف فارسی در ASP.Net MVC
یک مورد دیگه که باعث بروز این مشکل میشه افزونه فایرباگ هست. علتش رو نمی‌دونم اما در زمان فعال بودن فایرباگ دو بار درخواست برای تصویر امنیتی ارسال و مقدار درون کوکی با تصویری که می‌بینید متفاوت میشه.
درحالی که در زمان خاموش بودن فایرباگ این مشکل وجود نداره.