ব্যবহারকারী-ভাগ করা প্রশ্নগুলি: গতিশীল এসকিউএল বনাম এসকিউএলসিএমডি


15

আমাকে অনেকগুলি foo.sqlক্যোয়ারী রিফ্যাক্টর এবং ডকুমেন্ট করতে হবে যা ডিবি টেক সাপোর্টের একটি দল (গ্রাহক কনফিগারেশন এবং এর মতো জিনিসগুলির জন্য) ভাগ করবে। বিভিন্ন ধরণের টিকিট রয়েছে যা নিয়মিত আসে যেখানে প্রতিটি গ্রাহকের নিজস্ব সার্ভার এবং ডাটাবেস থাকে তবে অন্যথায় স্কিমাটি বোর্ড জুড়ে একই are

সঞ্চিত পদ্ধতিগুলি বর্তমানে কোনও বিকল্প নয়। আমি গতিশীল বা এসকিউএলসিএমডি ব্যবহার করব কিনা তা নিয়ে বিতর্ক করছি, এসকিউএল সার্ভারে আমি কিছুটা নতুন হওয়ায় আমি তেমন কিছু ব্যবহার করিনি।

এসকিউএলসিএমডি স্ক্রিপ্টিং আমি স্পষ্টভাবে আমার কাছে "দেখতে" ক্লিনার বলে মনে করি এবং প্রয়োজন অনুসারে প্রশ্নের মধ্যে ছোটখাটো পরিবর্তন করা সহজ, তবে ব্যবহারকারীকে এসকিউএলসিএমডি মোড সক্ষম করতে বাধ্য করে। ডাইনামিক আরও বেশি কঠিন কারণ স্ট্রিং ম্যানিপুলেশন ব্যবহার করে কোয়েরি লেখা হওয়ার কারণে সিনট্যাক্স হাইলাইটিং হ্রাস হ্রাস পেয়েছে।

এগুলি পরিচালনা করা হচ্ছে এবং পরিচালনা স্টুডিও 2012, এসকিউএল সংস্করণ 2008R2 ব্যবহার করে চালানো হচ্ছে। কোনও পদ্ধতির কিছু উপকার / বিভক্তি বা এসকিউএল সার্ভারের কোনও কোনও পদ্ধতি বা অন্য পদ্ধতিতে "সেরা অনুশীলন" কী কী? তাদের মধ্যে একটির কি অন্যের চেয়ে "নিরাপদ"?

গতিশীল উদাহরণ:

declare @ServerName varchar(50) = 'REDACTED';
declare @DatabaseName varchar(50) = 'REDACTED';
declare @OrderIdsSeparatedByCommas varchar(max) = '597336, 595764, 594594';

declare @sql_OrderCheckQuery varchar(max) = ('
use {@DatabaseName};
select 
    -- stuff
from 
    {@ServerName}.{@DatabaseName}.[dbo].[client_orders]
        as "Order"
    inner join {@ServerName}.{@DatabaseName}.[dbo].[vendor_client_orders]
        as "VendOrder" on "Order".o_id = "VendOrder".vco_oid
where "VendOrder".vco_oid in ({@OrderIdsSeparatedByCommas});
');
set @sql_OrderCheckQuery = replace( @sql_OrderCheckQuery, '{@ServerName}',   quotename(@ServerName)   );
set @sql_OrderCheckQuery = replace( @sql_OrderCheckQuery, '{@DatabaseName}', quotename(@DatabaseName) );
set @sql_OrderCheckQuery = replace( @sql_OrderCheckQuery, '{@OrderIdsSeparatedByCommas}', @OrderIdsSeparatedByCommas );
print   (@sql_OrderCheckQuery); -- For debugging purposes.
execute (@sql_OrderCheckQuery);

এসকিউএলসিএমডি উদাহরণ:

:setvar ServerName "[REDACTED]";
:setvar DatabaseName "[REDACTED]";
:setvar OrderIdsSeparatedByCommas "597336, 595764, 594594"

use $(DatabaseName)
select 
    --stuff
from 
    $(ServerName).$(DatabaseName).[dbo].[client_orders]
        as "Order"
    inner join $(ServerName).$(DatabaseName).[dbo].[vendor_client_orders]
        as "VendOrder" on "Order".o_id = "VendOrder".vco_oid
where "VendOrder".vco_oid in ($(OrderIdsSeparatedByCommas));

use ...আপনার লিপির উদ্দেশ্য কী ? পরবর্তী ক্যোয়ারের সঠিক সম্পাদন করা কি গুরুত্বপূর্ণ? আমি জিজ্ঞাসা করছি কারণ যদি বর্তমান ডাটাবেস পরিবর্তন করা আপনার কোয়েরির প্রত্যাশিত ফলাফলগুলির মধ্যে একটি হয় তবে ডায়নামিক এসকিউএল সংস্করণ কেবল এসইকিউএলসিএমডি প্রকরণের বিপরীতে বাহ্যিক স্কোপে নয়, ডায়নামিক ক্যোয়ারির স্কোপগুলিতে এটি পরিবর্তন করবে of অবশ্যই, শুধুমাত্র একটি সুযোগ আছে)।
অ্যান্ড্রি এম

useবিবৃতি সম্ভবত বাদ যেতে পারে যেমন সুযোগ এই বিশেষ স্ক্রিপ্ট সময় কোন পথে পরিবর্তন করা যাবে না। আমার কাছে ব্যবহারের একটি ছোট সংখ্যা রয়েছে যেখানে ক্রস-সার্ভার অনুসন্ধান থাকবে তবে এটি এই পোস্টের আওতার বাইরে হতে পারে।
ফ্রেঞ্চিস

উত্তর:


13

কেবল এগুলি থেকে বেরিয়ে আসার জন্য:

  • প্রযুক্তিগতভাবে বলতে গেলে এই দুটি অপশনই হ'ল "গতিশীল" / অ্যাডহক ক্যোয়ারী যা জমা না দেওয়া পর্যন্ত পার্স / বৈধ নয়। আর উভয় এসকিউএল ইনজেকশন সমর্থ যেহেতু তারা (স্থিতিমাপ নেই SQLCMD স্ক্রিপ্টের যদিও, যদি আপনি একটি সিএমডি স্ক্রিপ্ট থেকে একটি পরিবর্তনশীল মধ্যে ক্ষণস্থায়ী হয় তারপর আপনি প্রতিস্থাপন করার সুযোগ আছে 'সঙ্গে '', বা কাজের না যেখানে উপর নির্ভর করে হতে পারে যা ভেরিয়েবল ব্যবহার করা হচ্ছে)।

  • প্রতিটি পদ্ধতির পক্ষে বিভিন্ন মতামত রয়েছে:

    • এসএসএমএসে এসকিউএল স্ক্রিপ্টগুলি সহজেই সম্পাদনা করা যায় (এটি যদি প্রয়োজন হয় তবে এটি দুর্দান্ত) এবং এসকিউএলএমএমডি থেকে প্রাপ্ত ফলাফলের চেয়ে ফলাফলের সাথে কাজ করা সহজ। ডাউন-সাইডে, ব্যবহারকারী একটি আইডিইতে রয়েছে তাই এসকিউএলকে জগাখিচু করা সহজ, এবং এসকিউএল না জেনে আইডিই এটি বিভিন্ন ধরণের পরিবর্তন করা সহজ করে তোলে।
    • এসকিউএলসিএমডি.এক্সই এর মাধ্যমে স্ক্রিপ্টগুলি চালানো ব্যবহারকারীকে সহজেই পরিবর্তন করতে দেয় না (কোনও সম্পাদকে স্ক্রিপ্টটি সম্পাদনা না করে এবং প্রথমে এটি সংরক্ষণ না করে)। ব্যবহারকারীদের স্ক্রিপ্টগুলি পরিবর্তন করার কথা যদি মনে করা না হয় তবে এটি দুর্দান্ত। এই পদ্ধতিটি এর প্রতিটি সম্পাদন লগ করার অনুমতি দেয় for ডাউন-সাইডে, যদি নিয়মিত স্ক্রিপ্টগুলি সম্পাদনা করার প্রয়োজন হয় তবে এটি বেশ জটিল। অথবা, যদি ব্যবহারকারীদের কোনও ফলাফলের 100k সারিগুলির মাধ্যমে স্ক্যান করতে হয় এবং / অথবা এক্সেল বা কোনও কিছুতে সেই ফলাফলগুলি অনুলিপি করতে হয়, তবে এটি এই পদ্ধতির ক্ষেত্রেও কঠিন।

যদি আপনার সমর্থন ভাবেন লোকগুলি এইডক কোয়েরি না করে এবং কেবল সেই পরিবর্তনগুলি পূরণ করে তবে তাদের এসএসএমএসে থাকার দরকার নেই যেখানে তারা সেই স্ক্রিপ্টগুলি সম্পাদনা করতে এবং অযাচিত পরিবর্তন করতে পারে।

আমি পছন্দসই পরিবর্তনশীল মানগুলির জন্য ব্যবহারকারীকে প্রম্পট করার জন্য সিএমডি স্ক্রিপ্টগুলি তৈরি করব এবং তারপরে এই মানগুলির সাথে এসকিউএলসিএমডি.এক্সই কল করব । সিএমডি স্ক্রিপ্ট এমনকি সম্পাদিত কোনও ফাইলের জন্য লগ করতে পারে, জমা দেওয়া সময় স্ট্যাম্প এবং ভেরিয়েবল মান সহ।

প্রতিটি এসকিউএল স্ক্রিপ্টের জন্য একটি সিএমডি স্ক্রিপ্ট তৈরি করুন এবং একটি নেটওয়াক শেয়ার্ড ফোল্ডারে রাখুন। কোনও ব্যবহারকারী সিএমডি স্ক্রিপ্টে ডাবল ক্লিক করে এবং এটি কেবল কার্যকর।

এখানে একটি উদাহরণ যে:

  • ব্যবহারকারীকে সার্ভার নামের জন্য অনুরোধ জানায় (এটি এখনও পরীক্ষা করতে কোনও ত্রুটি নেই)
  • ব্যবহারকারীকে ডাটাবেসের নামের জন্য অনুরোধ জানায়
    • যদি খালি ছেড়ে যায় তবে এটি নির্দিষ্ট সার্ভারে ডাটাবেসগুলি তালিকাভুক্ত করবে এবং আবার অনুরোধ জানাবে
    • যদি ডাটাবেসের নামটি অবৈধ হয় তবে ব্যবহারকারীকে আবার অনুরোধ জানানো হবে
  • অর্ডারআইডিএসপ্রেটেডবাইকমাসের জন্য ব্যবহারকারীকে অনুরোধ জানায়
    • যদি ফাঁকা থাকে, ব্যবহারকারীকে আবার অনুরোধ জানায়
  • %OrderIDsSeparatedByCommas%এসকিউএলসিএমডি ভেরিয়েবল হিসাবে মান পাস করে এসকিউএল স্ক্রিপ্ট চালায়$(OrderIDsSeparatedByCommas)
  • উইন্ডোজ লগইন স্ক্রিপ্টটি চালানোর জন্য নামের একটি লগ ফাইলটিতে মৃত্যুদন্ড কার্যকর করার তারিখ, সময়, সার্ভারনাম, ডাটাবেসনাম এবং অর্ডারআইডিএসপ্যারটেডবাইকমাস লগ করে (এইভাবে, যদি লগ ডিরেক্টরিটি নেটওয়ার্ক থাকে এবং একাধিক লোক এটি ব্যবহার করে থাকে তবে কোনও লেখার দরকার নেই লগ ফাইলের বিষয়ে মতামত থাকতে পারে যদি USERNAME এন্ট্রি প্রতি ফাইলটিতে লগ করা থাকে)
    • লগ ফাইল ডিরেক্টরি উপস্থিত না থাকলে এটি তৈরি করা হবে

এসকিউএল স্ক্রিপ্ট পরীক্ষা করুন (নাম দেওয়া হয়েছে: ফিক্সপ্রোব্লেমএক্সকিউএল ):

SELECT  *
FROM    sys.objects
WHERE   [schema_id] IN ($(OrderIdsSeparatedByCommas));

সিএমডি স্ক্রিপ্ট (নাম দেওয়া হয়েছে: ফিক্স প্রব্লেমএক্স.কম ):

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET ScriptLogPath=\\server\share\RunSqlCmdScripts\LogFiles

CLS

SET /P ScriptServerName=Please enter in a Server Name (leave blank to exit): 

IF "%ScriptServerName%" == "" GOTO :ThisIsTheEnd

REM echo %ScriptServerName%

:RequestDatabaseName
ECHO.
SET /P ScriptDatabaseName=Please enter in a Database Name (leave blank to list DBs on %ScriptServerName%): 

IF "%ScriptDatabaseName%" == "" GOTO :GetDatabaseNames

SQLCMD -b -E -W -h-1 -r0 -S %ScriptServerName% -Q "SET NOCOUNT ON; IF (NOT EXISTS(SELECT [name] FROM sys.databases WHERE [name] = N'%ScriptDatabaseName%')) RAISERROR('Invalid DB name!', 16, 1);" 2> nul

IF !ERRORLEVEL! GTR 0 (
    ECHO.
    ECHO That Database Name is invalid. Please try again.

    SET ScriptDatabaseName=
    GOTO :RequestDatabaseName
)

:RequestOrderIDs
ECHO.
SET /P OrderIdsSeparatedByCommas=Please enter in the OrderIDs (separate multiple IDs with commas): 

IF "%OrderIdsSeparatedByCommas%" == "" (

    ECHO.
    ECHO Don't play me like that. You gots ta enter in at least ONE lousy OrderID, right??
    GOTO :RequestOrderIDs
)


REM Finally run SQLCMD!!
SQLCMD -E -W -S %ScriptServerName% -d %ScriptDatabaseName% -i FixProblemX.sql -v OrderIdsSeparatedByCommas=%OrderIdsSeparatedByCommas%

REM Log this execution
SET ScriptLogFile=%ScriptLogPath%\%~n0_%USERNAME%.log
REM echo %ScriptLogFile%

IF NOT EXIST %ScriptLogPath% MKDIR %ScriptLogPath%

ECHO %DATE% %TIME% ServerName=%ScriptServerName%    DatabaseName=[%ScriptDatabaseName%] OrderIdsSeparatedByCommas=%OrderIdsSeparatedByCommas%   >> %ScriptLogFile%

GOTO :ThisIsTheEnd

:GetDatabaseNames
ECHO.
SQLCMD -E -W -h-1 -S %ScriptServerName% -Q "SET NOCOUNT ON; SELECT [name] FROM sys.databases ORDER BY [name];"
ECHO.
GOTO :RequestDatabaseName

:ThisIsTheEnd
PAUSE

ScriptLogPathস্ক্রিপ্ট শীর্ষে পরিবর্তনশীল সম্পাদনা করতে ভুলবেন না ।

এছাড়াও, এসকিউএল স্ক্রিপ্টগুলি ( এসকিউএলএমএমডি.এক্সই-i জন্য কমান্ড-লাইন স্যুইচ দ্বারা নির্দিষ্ট ) পুরোপুরি যোগ্যতার পথ পেয়ে উপকার পেতে পারে তবে সম্পূর্ণ নিশ্চিত নয়।

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