मैं एक एसक्यूएल सीएलआर संबंधित समस्या के साथ एक निजी मित्र (जो अब भी एक ग्राहक है) की मदद करने की कोशिश कर रहा हूं। उसके पास एक डेटाबेस के साथ एक SQL सर्वर है जिसमें 3 .NET असेंबली इसमें एम्बेड किया गया है। उन्होंने मुझे डेटाबेस से असेंबली निकालने में मदद करने के लिए कहा और उन्हें डिस्क पर .dll फ़ाइलों के रूप में सहेजें। क्या यह भी संभव है?एसक्यूएल सर्वर 2005 से एक .NET असेंबली निकालने
उत्तर
हां, यह संभव है। असेंबली का वास्तविक बाइनरी प्रतिनिधित्व आपके सर्वर के लिए SQL कैटलॉग में रहता है। अर्थात्, यदि आप sys.assembly_files और sys.assemblies के बीच जुड़ते हैं तो आप की सभी जानकारी प्राप्त कर सकते हैं। असेंबली बाइनरी sys.assembly_files व्यू के सामग्री कॉलम में है।
लेकिन आदेश एसक्यूएल सर्वर से और आप कुछ नेट कोड एक ही डाटाबेस जहां विधानसभाओं का उल्लेख अब स्थित हैं पर चलने की जरूरत है कि लिखने के लिए होगा डिस्क पर एक फ़ाइल में द्विआधारी प्रतिनिधित्व निकालने के लिए में। दृश्य स्टूडियो में एक SQL CLR परियोजना शुरू करने और निम्न कोड के साथ यह करने के लिए एक वर्ग जोड़ें:
using System;
using System.IO;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Security.Permissions;
namespace ExtractSqlAssembly {
[PermissionSet(SecurityAction.Demand, Unrestricted = true, Name = "FullTrust")]
public partial class SaveSqlAssembly {
[SqlProcedure]
public static void SaveAssembly(string assemblyName, string path) {
string sql = @"SELECT AF.content FROM sys.assembly_files AF JOIN sys.assemblies A ON AF.assembly_id = A.assembly_id where AF.file_id = 1 AND A.name = @assemblyname";
using (SqlConnection conn = new SqlConnection("context connection=true")) {
using (SqlCommand cmd = new SqlCommand(sql, conn)) {
SqlParameter param = new SqlParameter("@assemblyname", SqlDbType.VarChar);
param.Value = assemblyName;
cmd.Parameters.Add(param);
cmd.Connection.Open(); // Read in the assembly byte stream
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
SqlBytes bytes = reader.GetSqlBytes(0);
// write the byte stream out to disk
FileStream bytestream = new FileStream(path, FileMode.CreateNew);
bytestream.Write(bytes.Value, 0, (int)bytes.Length);
bytestream.Close();
}
}
}
}
}
तो परियोजना का निर्माण करने और अपने डेटाबेस के लिए यह की तैनाती। सुनिश्चित करें कि CLR SQL सर्वर पर सक्षम कॉन्फ़िगरेशन विकल्प सक्षम है। यह शायद पहले से ही सक्षम है, क्योंकि आपके पास इस पर असेंबली हैं।
sp_configure 'clr enabled', 1
go
reconfigure
go
एक और बात यह है कि आप के बारे में पता करने की आवश्यकता है डिफ़ॉल्ट एसक्यूएल सर्वर द्वारा है आप लिखने की अनुमति नहीं हो सकता है: मामले में clr निष्पादन नहीं सक्षम आप इसे सक्षम करने के लिए पर SSMS निम्नलिखित कोड चलाया जा सकता है .NET कोड से डिस्क पर। अगर आपको एसएसएमएस में संग्रहीत प्रक्रिया को कॉल करके उपरोक्त कोड चलाते समय फ़ाइलियो सुरक्षा त्रुटि प्राप्त होती है, तो आपको असेंबली के लिए उचित अनुमति सेट कॉन्फ़िगर करने की आवश्यकता होगी। आप एसएसएमएस के माध्यम से ऐसा कर सकते हैं: नई असेंबली पर राइट-क्लिक करें और गुण संवाद में अनुमति सेट देखें। इसे बाहरी एक्सेस पर सेट करें। अब आप SSMS में निम्नलिखित कोड चलाकर अपने विधानसभाओं निर्यात करने के लिए सक्षम होना चाहिए:
exec SaveAssembly 'AssemblyName', 'f:\path\to\assemblyname.dll'
आशा यह आपके लिए काम करता है ...
हां।
एक select * from sys.assembly_files
कर विधानसभा की आईडी को खोजने के लिए आप चाहते हैं
DECLARE @IMG_PATH VARBINARY(MAX)
DECLARE @ObjectToken INT
SELECT @IMG_PATH = content FROM sys.assembly_files WHERE assembly_id = 65536
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @IMG_PATH
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, 'c:\temp\myassembly.dll', 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken
भयानक नीचे मेरा उत्तर देखें। सरल और साफ धन्यवाद। –
प्रीत का समाधान मेरे लिए काम किया है, लेकिन मैं ओले स्वचालन कॉन्फ़िगर करने के लिए एसक्यूएल सर्वर 2008 R2 पर काम करने के लिए किया था। ध्यान दें कि SaveToFile काम नहीं करता है - न ही यह एक त्रुटि संदेश देता है - जब तक कि SQL सर्वर को उस निर्देशिका की अनुमति न हो। मेरे मामले में मैंने SQL सर्वर इंस्टेंस के डेटा फ़ोल्डर का उपयोग किया जो ठीक काम करता था।
EXECUTE SP_CONFIGURE 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
GO
EXEC sp_configure 'Ole Automation Procedures', 1;
RECONFIGURE WITH OVERRIDE
GO
DECLARE @IMG_PATH VARBINARY(MAX)
DECLARE @ObjectToken INT
SELECT @IMG_PATH = content FROM sys.assembly_files WHERE assembly_id = 65546
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @IMG_PATH
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\myassembly.dll', 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken
EXEC sp_configure 'Ole Automation Procedures', 0;
RECONFIGURE WITH OVERRIDE
GO
EXECUTE SP_CONFIGURE 'show advanced options', 0
RECONFIGURE WITH OVERRIDE
GO
जोनास 'दृष्टिकोण एक कंसोल एप्लिकेशन या LINQPad स्क्रिप्ट के रूप में भी ठीक काम करता है - कोई जरूरत के लिए कोड, एसक्यूएल प्रक्रिया के भीतर स्थानीय स्तर पर निष्पादित किया जाना है के रूप में वह तात्पर्य नहीं है।जैसे किसी डेटाबेस से tSQLt विधानसभा (एक परीक्षण उपकरण) निकालने:
void Main()
{
var assemblyName = "tSQLtCLR";
var serverName = "localhost";
var databaseName = "MyDb";
var targetDir = Environment.ExpandEnvironmentVariables("%TEMP%");
var targetFile = Path.Combine(targetDir, assemblyName) + ".dll";
var sql = @"SELECT AF.content FROM sys.assembly_files AF JOIN sys.assemblies A ON AF.assembly_id = A.assembly_id where AF.file_id = 1 AND A.name = @assemblyName";
var connectionString = string.Format("Data Source={0};Initial Catalog={1};Integrated Security=true", serverName, databaseName);
using(var connection = new System.Data.SqlClient.SqlConnection(connectionString)){
connection.Open();
var command = connection.CreateCommand();
command.CommandText = sql;
command.Parameters.Add("@assemblyName", assemblyName);
using(var reader = command.ExecuteReader()){
if(reader.Read()){
var bytes = reader.GetSqlBytes(0);
File.WriteAllBytes(targetFile, bytes.Value);
Console.WriteLine(targetFile);
}else{
throw new Exception("No rows returned");
}
}
}
}
प्रीत और नैट के समाधान ले रहा है और उन्हें एक स्क्रिप्ट है कि एक कर्सर का उपयोग करके सभी clr procs निर्यात करेगा में बदल:
EXECUTE SP_CONFIGURE 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
GO
EXEC sp_configure 'Ole Automation Procedures', 1;
RECONFIGURE WITH OVERRIDE
GO
RAISERROR ('Starting...', 0, 1) WITH NOWAIT
DECLARE @ObjectToken INT
DECLARE @AssemblyLocation VARCHAR(MAX)
DECLARE @Msg VARCHAR(MAX)
DECLARE @Content VARBINARY(MAX)
DECLARE @Count AS INT = (SELECT COUNT(name) FROM sys.assembly_files)
DECLARE AssemblyFiles CURSOR FAST_FORWARD
FOR
SELECT
CAST(ROW_NUMBER() OVER (ORDER BY name) AS VARCHAR(10)) + ' of ' + CAST(@Count AS VARCHAR(10)) + ' - ' + name AS Msg,
'[a location the server can write to]' + name + '.dll' AS AssemblyLocation,
content
FROM
sys.assembly_files
ORDER BY
name
OPEN AssemblyFiles
FETCH NEXT FROM AssemblyFiles
INTO @Msg, @AssemblyLocation, @Content
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @Content
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @AssemblyLocation, 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken
RAISERROR (@Msg, 0, 1) WITH NOWAIT
FETCH NEXT FROM AssemblyFiles
INTO @Msg, @AssemblyLocation, @Content
END
CLOSE AssemblyFiles
DEALLOCATE AssemblyFiles
RAISERROR ('Done', 0, 1) WITH NOWAIT
EXEC sp_configure 'Ole Automation Procedures', 0;
RECONFIGURE WITH OVERRIDE
GO
EXECUTE SP_CONFIGURE 'show advanced options', 0
RECONFIGURE WITH OVERRIDE
GO
मैं इस समस्या का एक आसान समाधान मिला है, जो आवश्यक था क्योंकि sp_OACreate
SQL सर्वर 2017 (कम से कम, लिनक्स संस्करण नहीं) के लिए उपलब्ध प्रतीत नहीं होता है।
तुम बस बीसीपी उपयोगिता, डिस्क पर एक फ़ाइल में विधानसभा लिखने के लिए तो जैसे उपयोग कर सकते हैं:
/opt/mssql-tools/bin/bcp "SELECT content FROM sys.assembly_files WHERE name = '${ASSEMBLY_NAME}'" \
queryout /tmp/my_assembly.so -f bcp.fmt \
-S localhost -U sa -P "${SA_PASSWORD}" -d master
और इस प्रारूप फ़ाइल (bcp.fmt) का उपयोग करें:
13.0
1
1 SQLBINARY 0 0 "" 1 content ""
फ़ाइल जिसके परिणामस्वरूप (/tmp/my_assembly.so), एक विधानसभा के निर्माण में इस्तेमाल किया जा सकता है ताकि तरह:
CREATE ASSEMBLY [MyAssembly] AUTHORIZATION [dbo]
FROM '/tmp/my_assembly.so' WITH PERMISSION_SET = SAFE;
- 1. सीएलआर असेंबली 64 बिट एसक्यूएल सर्वर 2005
- 2. माइक्रोसॉफ्ट एसक्यूएल सर्वर 2005
- 3. .NET 3.5 असेंबली एसक्यूएल 2005 सीएलआर का उपयोग करना?
- 4. टी-एसक्यूएल एसक्यूएल सर्वर 2005
- 5. एमएस एसक्यूएल सर्वर 2005
- 6. एसक्यूएल सर्वर 2005
- 7. एसक्यूएल सर्वर 2005
- 8. एसक्यूएल सर्वर 2005/2008
- 9. एसक्यूएल सर्वर 2005
- 10. एसक्यूएल सर्वर 2005
- 11. चेक सर्वर (एसक्यूएल सर्वर 2005
- 12. एसक्यूएल सर्वर 2005: परिवर्तनीय
- 13. एमएस एसक्यूएल सर्वर 2005
- 14. एसक्यूएल सर्वर 2005
- 15. एमएस एसक्यूएल सर्वर 2005
- 16. एसक्यूएल सर्वर 2005
- 17. एसएएस एसक्यूएल सर्वर 2005
- 18. एसक्यूएल सर्वर 2005: टी-एसक्यूएल अस्थायी रूप से एक ट्रिगर
- 19. एसक्यूएल सर्वर 2005
- 20. एक चुनिंदा कथन एसक्यूएल सर्वर 2005
- 21. एसक्यूएल सर्वर 2005 (या 08)
- 22. एमएस एसक्यूएल सर्वर 2005 एक्सप्रेस
- 23. एसक्यूएल सर्वर 2005 डाटाबेस 'रिकवरी'
- 24. एसक्यूएल सर्वर 2005/2008: ट्रांसएक्ट-एसक्यूएल
- 25. एसक्यूएल क्वेरी SQL सर्वर 2005
- 26. माइक्रोसॉफ्ट एसक्यूएल सर्वर 2005 स्ट्रिंग
- 27. एसक्यूएल सर्वर 2005: एकल क्वेरी
- 28. अद्यतन सेट में एसक्यूएल (एसक्यूएल सर्वर 2005)
- 29. एसक्यूएल सर्वर 2005: निरर्थक विदेशी कुंजी बाधा
- 30. एसक्यूएल सर्वर 2008 डीबी * को * एसक्यूएल सर्वर 2005
यह दृष्टिकोण ठीक काम करता है जब ext मार डाला कभी भी - आपको SQLCLR मार्ग पर जाने की आवश्यकता नहीं है। – piers7