كيفية الحصول على المخزن sp_executesql يؤدي إلى متغير؟
-
03-07-2019 - |
سؤال
ولدي قطعة من SQL ديناميكية ولست بحاجة للتنفيذ، وبعد ذلك تحتاج إلى تخزين النتيجة إلى متغير.
وأعرف أنني أستطيع أن استخدام sp_executesql
ولكن لا يمكن العثور على أمثلة واضحة حول حول كيفية القيام بذلك.
المحلول
إذا كان لديك المعلمات OUTPUT يمكنك القيام به
DECLARE @retval int
DECLARE @sSQL nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);
DECLARE @tablename nvarchar(50)
SELECT @tablename = N'products'
SELECT @sSQL = N'SELECT @retvalOUT = MAX(ID) FROM ' + @tablename;
SET @ParmDefinition = N'@retvalOUT int OUTPUT';
EXEC sp_executesql @sSQL, @ParmDefinition, @retvalOUT=@retval OUTPUT;
SELECT @retval;
ولكن إذا لم تقم بذلك، ولا يمكن تعديل SP:
-- Assuming that your SP return 1 value
create table #temptable (ID int null)
insert into #temptable exec mysp 'Value1', 'Value2'
select * from #temptable
وليس جميلا، ولكن يعمل.
نصائح أخرى
DECLARE @tab AS TABLE (col VARCHAR(10), colu2 varchar(10))
INSERT into @tab EXECUTE sp_executesql N'SELECT 1 as col1, 2 as col2 union all SELECT 1 as col1, 2 as col2 union all SELECT 1 as col1, 2 as col2'
SELECT * FROM @tab
DECLARE @vi INT
DECLARE @vQuery NVARCHAR(1000)
SET @vQuery = N'SELECT @vi= COUNT(*) FROM <TableName>'
EXEC SP_EXECUTESQL
@Query = @vQuery
, @Params = N'@vi INT OUTPUT'
, @vi = @vi OUTPUT
SELECT @vi
وتعلنvariable كثافة العمليات
واكسيكvariable = proc_name
وعموما لا تستخدم القيم العودة إلى "العودة" نتيجة لذلك سوى العودة نجاح (0) أو رقم خطأ (1-65K). وقبل كل شيء يبدو للإشارة إلى أن المخزن sp_executesql لا ترجع قيمة، وهو قول غير صحيح. سوف المخزن sp_executesql العودة 0 من أجل نجاح وأي رقم آخر للفشل.
في أدناه،i سيعود 2727
DECLARE @s NVARCHAR(500)
DECLARE @i INT;
SET @s = 'USE [Blah]; UPDATE STATISTICS [dbo].[TableName] [NonExistantStatisticsName];';
EXEC @i = sys.sp_executesql @s
SELECT @i AS 'Blah'
سوف وSSMS إظهار هذا جي اس 2727، مستوى 11 حالة 1، خط 1 لا يمكن العثور على مؤشر "NonExistantStaticsName".
ونعلن الجدولValueTable ( VARCHAR قيمة (100) )
SELECT @sql = N'SELECT SRS_SizeSetDetails.'+@COLUMN_NAME+' FROM SRS_SizeSetDetails WHERE FSizeID = '''+@FSizeID+''' AND SRS_SizeSetID = '''+@SRS_SizeSetID+'''';
INSERT INTO @ValueTable
EXEC sp_executesql @sql;
SET @Value='';
SET @Value = (SELECT TOP 1 Value FROM @ValueTable)
DELETE FROM @ValueTable
إذا كنت ترغب في عودة أكثر من 1 القيمة تستخدم هذا:
DECLARE @sqlstatement2 NVARCHAR(MAX);
DECLARE @retText NVARCHAR(MAX);
DECLARE @ParmDefinition NVARCHAR(MAX);
DECLARE @retIndex INT = 0;
SELECT @sqlstatement = 'SELECT @retIndexOUT=column1 @retTextOUT=column2 FROM XXX WHERE bla bla';
SET @ParmDefinition = N'@retIndexOUT INT OUTPUT, @retTextOUT NVARCHAR(MAX) OUTPUT';
exec sp_executesql @sqlstatement, @ParmDefinition, @retIndexOUT=@retIndex OUTPUT, @retTextOUT=@retText OUTPUT;
والقيم التي يتم إرجاعها فيretIndex وretText
وكان هذا منذ وقت طويل، لذلك لست متأكدا إذا كان لا يزال بحاجة إلى هذا، ولكن هل يمكن استخداممتغير ROWCOUNT لمعرفة عدد الصفوف تأثرت مع بيان مزود السابق.
وهذا مفيد على سبيل المثال عندما كنت بناء بيانا تحديث دينامية وتشغيله مع إكسيك. سوفROWCOUNT تبين كيف تم تحديث العديد من الصفوف.
وهذا عمل بالنسبة لي:
DECLARE @SQL NVARCHAR(4000)
DECLARE @tbl Table (
Id int,
Account varchar(50),
Amount int
)
-- Lots of code to Create my dynamic sql statement
insert into @tbl EXEC sp_executesql @SQL
select * from @tbl