Maybe the solution can be so easy but I can't find it so I write here for some help.
We have this sql function:
CREATE FUNCTION [dbo].[updateExcel]
(
-- Add the parameters for the function here
#cell VARCHAR(4),
#description VARCHAR(200)
)
RETURNS BIT
AS
BEGIN
DECLARE #sql NVARCHAR(1000)
SET #sql = 'UPDATE openquery(LinkedServer2ExcelFile, ''SELECT * FROM [Sheet1$'+#cell+':'+#cell+']'') set F1 = '''+#description+''''
--PRINT #sql
EXEC sp_executesql #sql
RETURN 0
END
that we use to update some excel file
EXEC #Result = updateExcel 'somecell', 'somevalue'
The problem is that after this update the excel has a bigger size. But when we open it and save it again, the file's size get normal again
I hope to find here some answers ...
Thanx !!!
Related
I have stored procedure & cursor loop which I am using to add data in main table issue is I am adding data from csv file to temp table and from temp table to main table
alter PROCEDURE [dbo].[CreateHub]
#HubName varchar(100)
AS
INSERT INTO dbo.HUB1
(HUB_NAME)
SELECT #HubName
WHERE (NOT EXISTS
(SELECT ID_HUB, HUB_NAME
FROM dbo.HUB1
WHERE (HUB1.hub_name = #HubName)))
SELECT ID_HUB AS newHubId
FROM dbo.HUB1
WHERE (hub1.hub_name = #HubName)
GO
Once this is done, there is another code which is doing bulk insert from csv file and running cursor loop for adding data in main table
bulk insert [dbo].[HUB_temp]
from 'C:\POPAD-DAT\HUB1.csv'
with (fieldterminator = ',', rowterminator = '\n')
go
DECLARE #sSQL AS nVARCHAR(100)
DECLARE #ItemsFromCSV AS nvarchar(200)
DECLARE sql_cursor_hub CURSOR
FOR SELECT HUB_NAME FROM HUB_temp
OPEN sql_cursor_hub
FETCH NEXT FROM sql_cursor_hub
INTO #ItemsFromCSV -- Multiple variables for multiple CSV columns will be required
WHILE ##FETCH_STATUS = 0
BEGIN
set #sSQL = 'EXEC [dbo].[CreateHub] ' + #ItemsFromCSV -- AND OTHER Parameters
print #sSQl
EXECUTE sp_executesql #sSQL
FETCH NEXT FROM sql_cursor_hub
END
CLOSE sql_cursor_hub;
DEALLOCATE sql_cursor_hub;
Running cursor is not adding data its showing like same id and showing different u=hubname but not inserting data
While if I am running separately executing SP it is adding like this
EXEC [dbo].[CreateHub] 'SGGSP30'
EXEC [dbo].[CreateHub] 'USGSP20'
can you please help where exactly iam going wrong
You forgot to do INTO in the second fetch
WHILE ##FETCH_STATUS = 0
BEGIN
set #sSQL = 'EXEC [dbo].[CreateHub] ' + #ItemsFromCSV -- AND OTHER Parameters
print #sSQl
EXECUTE sp_executesql #sSQL
-- This is changed
FETCH NEXT FROM sql_cursor_hub INTO #ItemsFromCSV
END
You should also take care of your parameter declarations, #ItemsFromCSV is varchar(200) but the stored proc parameter is only varchar(100) and #sSQL is only 100 in size but you add #ItemsFromCSV to it.
I'm trying to append table name dynamically to SQL Server stored procedure, but I get an error:
couldn't find the stored procedure 's'
Code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[atest_demo_sp]
#name varchar(10)
AS
BEGIN
Declare #tname nvarchar
Declare #sql nvarchar
set #tname = #name
Set #sql = 'select * from ' + convert(varchar(10), #tname)
-- select #sql
execute sp_executesql #sql
END
You need to explicitly define a length for your string variables!
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[atest_demo_sp]
#name varchar(10)
AS
BEGIN
Declare #tname nvarchar(200) -- DEFINE A LENGTH HERE !!!
Declare #sql nvarchar(200) -- DEFINE A LENGTH HERE !!!
set #tname = #name
Set #sql = N'select * from ' + convert(nvarchar(10), #tname)
-- select #sql
execute sp_executesql #sql
END
Otherwise, your variables #tname and #sql will be exactly 1 character long! Probably not what you want!
See this blog post for more details: Bad habits to kick : declaring VARCHAR without (length)
Also, as a side note: either pick varchar (non-Unicode), or use nvarchar (Unicode) - but don't mix the two. And if you use nvarchar, you should always use the N'...' notation for assigning string literals.
The issue with the set #tname = #name, no need to assign the varchar to nvarchar here. Avoid the #tname variable and directly use #name in the SET statement since it is already varchar.
Hope the #name's first character only assigning to #tname. Also need to define the #sql to some length.
Use the below statement, it will work:
Declare #sql varchar(100);
Set #sql = 'select * from ' + #name
I have a problem with treating table name as variable as I need to put the results to different table each month automatically (without using any advanced procedures to make this query dynamic). Can somebody help me to modify this code and make it work?
declare #exp_dte as date;
set #exp_dte='2015-12-31';
print (#exp_dte);
declare #tab_mth as nvarchar(max);
set #tab_mth=year(#exp_dte)*100+month(#exp_dte);
print (#tab_mth);
declare #tab_name as nvarchar(max)
set #tab_name='mis_anl.dbo.BIK_' + #tab_mth
print (#tab_name);
IF OBJECT_ID (N'#tab_name', N'U') IS NOT NULL
begin
drop table #tab_name
end
select distinct
*
into #tab_name
from table_x
You have to use dynamic SQL to set name at runtime:
DECLARE #exp_dte DATE = '2015-12-31';
DECLARE #tab_name SYSNAME = '[dbo].' + QUOTENAME('BIK_' + FORMAT(#exp_dte, 'yyyyMM'));
IF OBJECT_ID (#tab_name, N'U') IS NOT NULL
BEGIN
EXEC('DROP TABLE' + #tab_name);
END
DECLARE #sql NVARCHAR(MAX) = N'SELECT DISTINCT *
INTO #tab_name
FROM table_x';
SET #sql = REPLACE(#sql, '#tab_name', #tab_name);
EXEC [dbo].[sp_executesql] #sql;
LiveDemo
Remarks:
Try to be more conscise
You could use FORMAT to get yyyyMM (SQL Server 2012+)
Always QUOTENAME generated identifiers to avoid SQL Injection attacks
I strongly recommend to read The Curse and Blessings of Dynamic SQL especially CREATE TABLE #tbl.
use dynamic sql ,you cant user table names as variables
declare #exp_dte as date;
set #exp_dte='2015-12-31';
declare #tab_mth as nvarchar(max);
set #tab_mth=year(#exp_dte)*100+month(#exp_dte);
declare #tab_name as nvarchar(max)
set #tab_name='mis_anl.dbo.BIK_' + #tab_mth
declare #sql1 nvarchar(max)
set #sql1='drop table '+#tab_name;
IF exists(select 1 from information_schema.tables where table_name=#tab_name)
begin
exec(#sql1);
end
declare #sql nvarchar(max)
set #sql='
select distinct
*
into '+#tab_name+'
from table_x'
exec (#sql)
I try to bulk insert different files.
When i code it like:
SET #xml=( Select * From OPENROWSET(
BULK 'C:\Data\csvToXml.xml',SINGLE_BLOB)x)
it is working.
If i take path as parameter like:
SET #Path= 'C:\Data\csvToXml.xml'
SET #SqlStmt= N' Select #xmlDoc=( Select * From OPENROWSET(
BULK '''+#Path+''' ,SINGLE_BLOB)x)'
exec sp_executesql #SqlStmt, N'#xmlDoc XML',#xmlDoc
#xmlDoc seems empty. I cannot find where I'm wrong.
Thanks for help.
Came here looking for a solution to my own problem but ended up solving this one!
DECLARE #Output int = 0;
DECLARE #params nvarchar(max) = N'#DesiredValue int OUTPUT';
DECLARE #sql_string nvarchar(max) = N'SELECT #DesiredValue = 13';
EXECUTE sp_executesql #sql_string, #params, #DesiredValue = #Output OUTPUT
SELECT #Output -- yields 13
It turns out you need to pass the keyword OUTPUT not only in the #params argument but also on the variables you wish to retrieve. The "#DesiredValue = #Output OUTPUT" looks a little odd because #Output is taking the value of #DesiredValue rather than the other way around.
Documentation.
How do I use a variable for Column name in Scalar-Valued Function?
CREATE FUNCTION [dbo].[GetValue]
(
#ID varchar(36),
#PreprtyName varchar(150)
)
RETURNS varchar(250)
AS
BEGIN
DECLARE #RetVal varchar(MAX)
DECLARE #SQL varchar(MAX)
SET #RetVal =''
SET #SQL = 'SET #RetVal = (Select '+ #PreprtyName + ' FROM TableMedia WHERE ID = '''+ #ID +')'''
exec #SQL
SET #RetVal = #RetVal
RETURN #RetVal
END
Getting error Could not find "Could not find stored procedure"
Here is what I'm trying to avoid.
SELECT pr.ProductID, tManufacturerImage.Image, tMediaCenter.ManualFileName,tMediaCenter.BrochureFileName, tMediaCenter.AssemblyFileName
FROM tMediaCenter RIGHT OUTER JOIN
tProduct AS pr INNER JOIN
tmp_dmi AS dmi ON REPLACE(REPLACE(pr.SKU, 'ACS', ''), 'DMI', '') = RTRIM(LTRIM(dmi.pri_SKU)) ON tMediaCenter.ProductID = pr.ProductID LEFT OUTER JOIN
tManufacturer INNER JOIN
tManufacturerImage ON tManufacturer.ManufacturerID = tManufacturerImage.ManufacturerID ON pr.ManufacturerID = tManufacturer.ManufacturerID
WHERE (pr.ManufacturerID = 'f35fc01680-4938-4070-a367-38c31efb01f') AND (dmi.MAP IS NULL) AND (pr.ParentID <> '')
this does not work for me.
You can't. A user-defined function does not support dynamic SQL. You will need to do this with a stored procedure instead, or better define your ultimate goal instead of telling us you need to solve it with dynamic SQL in a function.
CREATE PROCEDURE [dbo].[GetValues]
#PreprtyName VARCHAR(150)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'SELECT ' + #PreprtyName + ' FROM dbo.Table;';
EXEC sp_executesql #sql;
END
GO
You won't have an easy time doing this inline in your query, sorry. The issue is that there is no way to do this from a function, and there is no way to call a stored procedure for each row in a single query. You could construct a loop and everything else but I think the above procedure fits your requirement without all that extra work and overhead.
If you need to limit it to a certain set of ID values, you'll need to describe how you're trying to do that now.