I am using the RODBC package which I am applying on a Microsoft SQL Server 2012.
Now I have discovered a phenomenon that puzzles me.
If I run the following query with the RODBC command sqlQuery, then, in R, I will get back an empty data frame with the columns Country, CID, PriceID and WindID.
DECLARE #tbl_IDs TABLE
(
Country nvarchar(30),
CID nvarchar(5),
PriceID int,
WindID int
)
SELECT * FROM #tbl_Ids
So far, everything is fine.
However, if I try to write a record to the table variable and execute
DECLARE #tbl_IDs TABLE
(
Country nvarchar(30),
CID nvarchar(5),
PriceID int,
WindID int
)
INSERT INTO #tbl_IDs
VALUES
('Germany', 'DE', 112000001, 256000002);
SELECT * FROM #tbl_Ids
Then, in R, the result will be an empty character instead of a dataframe with one record. Still the same query works perfectly with SQL Server Management Studio.
Also, we have traced the behaviour of the DB Server while the R-Query is executed and it seems the server handles it perfectly. It seems that the RODBC interface has a problem to return the result to the R console.
Does anybody have an idea how this issue can be resolved?
Try toggling NOCOUNT as below:
old_qry <- "
DECLARE #tbl_IDs TABLE
(
Country nvarchar(30),
CID nvarchar(5),
PriceID int,
WindID int
)
INSERT INTO #tbl_IDs
VALUES
('Germany', 'DE', 112000001, 256000002);
SELECT * FROM #tbl_Ids
"
##
new_qry <- "
SET NOCOUNT ON;
DECLARE #tbl_IDs TABLE
(
Country nvarchar(30),
CID nvarchar(5),
PriceID int,
WindID int
);
INSERT INTO #tbl_IDs
VALUES
('Germany', 'DE', 112000001, 256000002);
SET NOCOUNT OFF;
SELECT * FROM #tbl_Ids
"
R> sqlQuery(tcon, gsub("\\n", " ", old_qry))
#character(0)
R> sqlQuery(tcon, gsub("\\n", " ", new_qry))
# Country CID PriceID WindID
#1 Germany DE 112000001 256000002
Basically you want to SET NOCOUNT ON at the beginning of your code, and SET NOCOUNT OFF just before the final SELECT statement.
Since database server handles query correctly, save the multiple line action TSQL query as a SQL Server Stored Procedure and have R call it retrieving the resultset.
Do note you can even pass parameters in the EXEC sp line from R to MSSQL. Also as mentioned, include the SET NOCOUNT ON declaration in the query to avoid undesired result character(0):
library("RODBC");
conn <- odbcConnect("DSN Name",uid="***",pwd="***"); # WITH DSN
#conn <-odbcDriverConnect('driver={SQL Server};server=servername;database=databasename;
#trusted_connection=yes;UID=username; PWD=password') # WITH DRIVER
df<-sqlQuery(conn, "EXEC dbo.StoredProcName");
Good Morning.
I am facing a very strange problem. I have an Oracle stored procedure which will accept a VARCHAR2 parameter.
From my ASP.NET application, I am calling this stored procedure and passing a comma separated string to this parameter.
The length of the comma separated string is 700 characters (including commas).
Now the problem is Oracle procedure is returning the error "3421: Application uses a value of the wrong type for the current operation".
If I delete some content of the input string and send it to procedure, then it is running successfully.
I read that VARCHAR2 in Oracle accepts a maximum of 4000 characters. I am sending only 700 characters. Still it is not taking it.
I tried to give the size to the procedure parameter. But it is giving compilation error and I read that we can't specify the size to oracle procedure prameter.
Can you please help me in resolving this issue.
Thanks
Srinivas
Input String that is sent to VAR33 in SP_TESTPROC procedure:
195083,195320,195815,196311,196247,196866,197002,197271,197294,197998,198107,
195322,195501,196537,196887,198194,198964,195125,196153,196454,196587,197158,
197082,197277,197482,198110,198312,196586,196403,196428,196510,196694,197075,
197543,198111,198351,195215,196399,197697,198200,198338,196267,195851,196069,
196435,197154,196411,196883,196898,196384,196892,196826,197138,198123,198590,
197384,196383,196438,197044,197831,198917,195787,198199,198120,195874,197155,
197262,197264,197447,198193,195730,196886,196891,196899,197076,198502,196232,
196538,196603,196857,196263,195380,196660,198041,198763,195616,195720,196430,
197559,197836,197844,198015,198666,195777,195951,196433,196795,195843,196398,
196448
create or replace PROCEDURE SP_TESTPROC
(VAR33 IN VARCHAR2 DEFAULT NULL
RC1 IN OUT OMWB_EMULATION.GLOBALPKG.RCT1)
AS
BEGIN
OPEN RC1 FOR
SELECT *
FROM TABLE1 A
INNER JOIN TABLE2 B ON A.ID = B.TABLE1ID
WHERE A.ID IN (select TO_NUMBER(regexp_substr(SPCWKF_CASEASSIGNMASTERQUERY.VAR33,'[^,]+', 1, level)) from dual
connect by regexp_substr(SPCWKF_CASEASSIGNMASTERQUERY.VAR33, '[^,]+', 1, level) is not null);
END SP_TESTPROC;
Try:
create or replace PROCEDURE SP_TESTPROC
(VAR33 IN VARCHAR2 DEFAULT NULL
RC1 IN OUT OMWB_EMULATION.GLOBALPKG.RCT1)
AS
BEGIN
VAR33 := regexp_replace(VAR33, '[^,0-9]', '');
OPEN RC1 FOR
SELECT *
..........
..........
..........
END SP_TESTPROC;
the above will remove all unwanted and "hidden" characters from the string.
For example, if you are calling the procedure in this way in your code:
proc_name('1234,2345,
2345,5432,
4545,7777', ..... )
then the string contains a few hidden line feed characters and some spaces, and these characters are obvioulsy 'not number' - but the procedure is trying to convert them into the number using to_number.
Take a look at this demo:http://sqlfiddle.com/#!4/f270bc/1
CREATE TABLE t(
x varchar(4000)
);
INSERT INTO t VALUES(
'1234,2345,
2345,5432,
4545,7777'
);
select x, dump(x)
from t;
and you will see that a dump of the output contains some 'hidden' charachers (20-space, 10-line feed):
Typ=1 Len=47: 49,50,51,52,44,50,51,52,53,44,10,32,32,32,32,32,32,32,32,50,51,52,53,44,
53,52,51,50,44,10,32,32,32,32,32,32,32,32,52,53,52,53,44,55,55,55,55
In my project EF calls a stored procedure which is shown below. It returns either 1 or scope identity.
On EF function imports, the stored procedure is listed with a return type of decimal.
When the stored procedure returns scope identity, everything is ok.
But when if condition of sp satisfies, ef throws error as
The data reader returned by the store data provider does not have enough columns for the query requested.
Pls help..
This is my stored procedure:
#VendorId int,
#ueeareaCode varchar(3),
#TuPrfxNo varchar(3),
#jeeSfxNo varchar(4),
#Tjode varchar(3),
#uxNo varchar(3),
#TyufxNo varchar(4),
#Iyuy bit
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
SET NOCOUNT ON;
IF EXISTS (Select dfen_id
from dbo.efe_phfedwn_eflwn
where
[yu] = #Tyuode and
[uy] = #TuyxNo and
[yuno] = #Tuo)
return 1
ELSE
Begin
INSERT INTO dbo.yu
....................
Select Scope_Identity()
End
END
The error tells us that EF is expecting a result set and when we use RETURN we don't get a result set. Your error means that the stored procedure is returning an integer but EF is expecting a decimal, so we just CAST the selected values to a decimal.
So modify the SQL so that we SELECT instead of RETURN, like so (not forgetting to use CAST):
IF EXISTS (Select cntct_ctr_phn_ln_id
from dbo.cntct_ctr_phn_ln
where
[toll_free_phn_area_cd] = #TollfreeareaCode and
[toll_free_phn_prfx_no] = #TollfreePrfxNo and
[toll_free_phn_sfx_no] = #TollfreeSfxNo)
SELECT CAST(1 AS decimal)
Then also CAST the result of SCOPE_IDENTITY() to a decimal:
SELECT CAST(SCOPE_IDENTITY() AS decimal)
I need help on SQL Server syntax to create some triggres that I´ve used with success on SQLite, but I'm having trouble with NEW.Table once it´s not part of SQL Server.
That´s my SQLite trigger code:
UPDATE EngineeringItems set ElevacaoFIT = CAST(round((select "Position Z" - MatchingPipeOD / 2 from EngineeringItems where PnPId = new.PNPID), 0) as INT) where PNPID = new.PNPID;
PNPID is the table pk!
EDIT 2:
Thanks again buddy!
I´ve tried your new code with a little modifications and SQL Server accepted it and trigger was created successfully. So the code is:
CREATE TRIGGER [ElevacaoFIT_Insert]
ON [dbo].[EngineeringItems]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE EngineeringItems
SET
ElevacaoFIT = CAST(ROUND((select EngineeringItems."Position Z" - (EngineeringItems.MatchingPipeOD / 2)
FROM
EngineeringItems INNER JOIN inserted ON EngineeringItems.PnPId = inserted.PnPId), 0) AS INT);
END
But now I get this message: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.! Any idea?
Sorry for bother you... Thanks again!!
Can you post what you have tried on SQL Server?
Something like the following may do it:
CREATE TRIGGER [dbo].[EngineeringItems_Trigger]
ON [dbo].[EngineeringItems]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE EngineeringItems
SET
ElevacaoFIT = CAST(round(("Position Z" - MatchingPipeOD / 2), 0) as INT)
FROM
EngineeringItems INNER JOIN inserted ON EngineeringItems.PnPId = inserted.PNPID;
END
ALTER PROCEDURE [dbo].[test]
#tour int,
#tourname varchar(50) OUTPUT,
#tourdepartures varchar(50) OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SET #tourname = (select [tour name] from dbo.products1 where tour = #tour)
SET #tourdepartures = (select ddate7 from dbo.TDEPART1 where tour = #tour and depart > convert(int,getdate()))
END
I want to use a stored procedure to populate a label on my asp.net page
and a dropdownlist
#tourname will be populated into a single label
while #tourdepartures will be multiple dates, that i want in a dropdownlist
however when i run my sp i get this error
Msg 512, Level 16, State 1, Procedure test, Line 21
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
(1 row(s) affected)
(1 row(s) affected)
and it works when i do
ALTER PROCEDURE [dbo].[test]
#tour int,
#tourname varchar(50) OUTPUT,
#tourdepartures varchar(50) OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SET #tourname = (select [tour name] from dbo.product where tour = #tour)
SET #tourdepartures = (select top 1 ddate7 from abcfilestest.dbo.TDEPART where tour = #tour and depart > convert(int,getdate()))
END
but it only gives me the first departure date
Get rid of the second SET and just return a resultset that you can use a reader with:
ALTER PROCEDURE [dbo].[test]
#tour int,
#tourname varchar(50) OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SET #tourname = (select [tour name] from dbo.products where tour = #tour)
select ddate7 from abcfilestest.dbo.TDEPART where tour = #tour and depart > convert(int,getdate())
END
You can try this to remove the error, but I don't think it's really what you want:
-- Insert statements for procedure here
SET #tourname = (select TOP 1 [tour name] from dbo.products where tour = #tour)
SET #tourdepartures = (select TOP 1 ddate7 from abcfilestest.dbo.TDEPART where tour = #tour and depart > convert(int,getdate()))
If you really want a list of all of the tour dates, change the last statement to
select ddate7 from abcfilestest.dbo.TDEPART where tour = #tour and depart > convert(int,getdate())
and parse the result set on the client as you usually would.
Also, for the love of all that's holy, rename that ddate7 column to something meaningful.
A scalar variable can only hold one value. The query you are using returns more than one value. YOu have several choices and the right one depends on your situation.
If you only want the latest date, use top 1 and order by date desc in your select.
If you want all the dates, then use a table variable not a scalar variable. I know I can use table variable in SQL Server 2008 as stored procedure parameter, not sure about 2005. You could just return 2 recordsets (so that you are consistent in what you are returning) or one output variable and one select instead of using output variables.