I am trying to insert data into a table based off what is already in the table. I read the table to get the number of records inserted for a certian month and then insert information based off if it is more or less than ten. After I read the table it throws an invalid object name when I try to do that insert. It's not an invalid object as it just read the table. If this is a permissions error how do I correct it? My code is below. Thanks,
Jason
declare #email VARCHAR(75),
#seminarNumber INT,
#isValidEmail BIT,
#monthlyTotal INT,
#statusCode INT
set #email = 'email#domain.com'
set #seminarNumber = '12345'
set #isValidEmail = dbo.RegexMatch('^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(([0-9]{1,3})|([a-zA-Z]{2,3})|(aero|coop|info|museum|name))$',#email)
if #isValidEmail = 1
begin
SELECT #monthlyTotal = count(mailid)
from Email_Tracking
where emailaddress = #email
and year(datesent) = year(getdate())
and month(datesent) = month(getdate())
if #monthlyTotal > 10
begin
set #statusCode = 1
end
else
begin
set #statusCode = 2
end
end
else
begin
set #statusCode = 3
end
if #statusCode = 1
begin
insert Email_Tracking ('seminarNumber','email','reasonNotSent')
values(#seminarNumber,#email,'Maximum surveys for the month have already been sent')
end
else if #statusCode = 2
begin
insert Email_Tracking ('seminarNumber','email','datesent')
values(#seminarNumber,#email,getdate())
end
else if #statusCode = 3
begin
insertEmail_Tracking ('seminarNumber','email','reasonNotSent')
values(#seminarNumber,#email,'Email address missing or invalid')
end
print #statusCode
try removing quotes from column names. so for eg:
insert Email_Tracking (seminarNumber,email,reasonNotSent)
values(#seminarNumber,#email,'Email address missing or invalid')
Related
Using Try/Catch with SqlServer 2008R2, is there a trick to getting some information out of the row that caused the error? For example,
BEGIN TRY
INSERT INTO MyTable
SELECT *
FROM #MyTableVar
END TRY
BEGIN CATCH
-- In here, is there some way to know, for example, MyTable.SomeColumn for the offending row?
END CATCH
This is what I ended up doing:
DECLARE #MyResults TABLE (
Id INT IDENTITY( 1, 1 )
TheKey VARCHAR(20),
Success BIT
)
-- Initially set Success to 1 for all rows
INSERT INTO #MyResults
SELECT TheKey, 1
FROM #MyTableVar
DECLARE #CurrentKey VARCHAR(20)
DECLARE #CurrentId INT
DECLARE incoming CURSOR FOR SELECT Id, TheKey FROM #MyResults
OPEN incoming
FETCH incoming into #Id, #CurrentKey
WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN TRY
INSERT INTO OfficialTable
SELECT *
FROM #MyTableVar TV
WHERE TV.TheKey = #CurrentKey
END TRY
BEGIN CATCH
-- On any failure, update the proper row in #MyResults
UPDATE #MyResults
SET Success = 0
WHERE TheKey = #CurrentKey AND Id = #CurrentId
END CATCH
FETCH NEXT FROM incoming INTO #Id, #CurrentKey
END
CLOSE incoming
SELECT * FROM #MyResults
In the CATCH, I know the key to #MyTableVar, so, I should be able to look up anything I need with that.
I need to split a field(Name) into Two (First Name and Last Name) based on a comma in Informix.
Example: "Mark, Wheeler J" has to be split as Mark and Wheeler. I have tried using SQL syntax but it gives me a syntax error in Informix. Please help me.
SELECT
SUBSTRING(name, 1, CHARINDEX(',', name ) - 1) AS FirstName,
SUBSTRING(name, CHARINDEX(',', name) + 1, 8000) AS LastName
FROM
employee
At first if you need to split such values and if you need to do it often then it would be easier to change your db schema:
rename column name into last_name
add column first_name
It has some advantages. You probably want to search employees by last name, and it is easy when you simply have such column. If last name is a part of name column then you must search using LIKE which is slower and worse.
Now you will have to change some data. If you have comma in last_name then in such column there is first and last name and you must split it.
If you have charindex() function you can do it with:
UPDATE employees SET last_name=substring(last_name FROM charindex(',', last_name)+1), first_name=substring(last_name FROM 1 FOR charindex(',', last_name)-1) WHERE charindex(',', last_name) > 0;
(you can also use TRIM() to remove spaces before/after comma which will be copied)
From comments I see that your version of Informix do not have CHARINDEX() function so you must upgrade db engine or use technique other than clean SQL.
If you can use programming language like Java or Python (for this example I use Jython: it is Python that work in Java environment and can use JDBC driver) you can:
db = DriverManager.getConnection(db_url, usr, passwd)
# prepare UPDATE:
pu = db.prepareStatement("UPDATE employee SET last_name=?, first_name=? WHERE id=?")
# search for names that must be changed:
pstm = prepareStatement("SELECT id, last_name FROM employee WHERE last_name LIKE '%,%')
# for each record found remember its `id`, split `first_name` and update it:
rs = pstm.executeQuery()
while (rs.next()):
id = rs.getInt(1)
name = rs.getString(2)
first_name, last_name = name.split(',')
pu.setString(1, last_name.strip())
pu.setString(2, first_name.strip())
pu.setInt(3, id)
rc = pu.executeUpdate()
I have faced a similar problem so I have developed a below function "char_cut" for informix 11.50 (haven't tried on different versions) Be warn that this is not the most efficient way to do that, but it works fine.
Usage:
SELECT
char_cut(name, ',', 1) AS FirstName,
char_cut(name, ',', 2) AS LastName
FROM
employee
Procedure:
create procedure char_cut( str_in varchar(255), separator_in char(1), field_in int )
returning varchar(255) ;
define res varchar(255);
define str_len int;
define pos_curr int;
define substr_start int;
define substr_length int;
define pos_char char(1);
IF field_in <= 0 THEN return ''; END IF;
LET res = '';
LET substr_start = 0;
LET substr_length = 0;
LET str_len = length(str_in);
FOR pos_curr = 1 TO str_len
LET pos_char = substr(str_in,pos_curr,1);
IF pos_char = separator_in THEN
LET field_in = field_in - 1;
END IF;
IF field_in = 1 and substr_start = 0 THEN
LET substr_start = pos_curr + DECODE(pos_char,separator_in,1,0);
END IF;
IF field_in <= 0 THEN
LET substr_length = pos_curr;
EXIT FOR; --KONIEC
END IF;
END FOR;
IF substr_length = 0 THEN
LET substr_length = str_len+1;
END IF;
IF substr_start = 0 THEN
LET substr_start = str_len+1;
END IF;
IF substr_length < substr_start THEN
LET substr_length = 0;
ELSE
LET substr_length = substr_length - substr_start;
END IF;
RETURN NVL(substring ( str_in from substr_start for substr_length ),'');
end procedure;
I'm trying to call the stored procedure attached below using Entity Framework 4.1 to cover 2 possible scenarios:
exec TEST_SP_OUTPUT 1
Should return a dataset from ACTIONTYPE table and #Success = 1
exec TEST_SP_OUTPUT 0
No dataset returned and #Success = 0
CREATE PROCEDURE [dbo].[TEST_SP_OUTPUT]
(
#Id int,
#Success int OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
IF (#Id = 1)
BEGIN
SELECT ActionName, ActionType FROM ACTIONTYPE
SET #Success = 1;
END
ELSE
SET #Success = 0;
END
The question is: can I handle both executions using a single Complex Type within the Entity Framework model?
Bear in mind that the scenario "exec TEST_SP_OUTPUT 0" is not returning any dataset or columns.
Correct me if I'm wrong, but I a possible solution may be setting dummy results for the second scenario:
CREATE PROCEDURE [dbo].[TEST_SP_OUTPUT]
(
#Id int,
#Success int OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
IF (#Id = 1)
BEGIN
SELECT ActionName, ActionType FROM ACTIONTYPE
SET #Success = 1;
END
ELSE
BEGIN
SELECT '' as ActionName, '' as ActionType
SET #Success = 0;
END
END
Cheers.
Juan.
Sorry, lots of code coming up..
I saw another question like this that used output parameters. I'm using the RETURN statement to return the value I want to use.
I have one stored procedure InsertMessage that looks like this:
ALTER PROCEDURE dbo.InsertNewMessage
(
#messageText text,
#dateTime DATETIME,
#byEmail bit,
#bySMS bit
)
AS
DECLARE #NewId int
BEGIN
BEGIN TRANSACTION
INSERT INTO MessageSet VALUES (#byEmail, #bySMS, #dateTime, #messageText)
SET #NewId = SCOPE_IDENTITY()
COMMIT
END
RETURN #NewId
which another stored procedure uses:
ALTER PROCEDURE dbo.InsertMessageFromUserToGroup
(
#userEmail nvarchar(256),
#groupId int,
#messageText text,
#bySMS bit,
#byEmail bit
)
AS
--Inserts a new message to a group
DECLARE #messageId int
DECLARE #dateTime DATETIME = GETDATE()
--First check if user is a part of the group
IF NOT EXISTS (SELECT userEmail FROM UserToGroupSet WHERE userEmail = #userEmail AND groupId = #groupId)
RETURN 'User not part of group'
ELSE --User is a part of the group, add message
BEGIN
BEGIN TRANSACTION
SET #messageId = [dbo].[InsertNewMessage](#messageText, #dateTime, #bySMS, #byEmail)
INSERT INTO MessageToUser VALUES(#userEmail, #messageId)
INSERT INTO MessageToGroup VALUES(#messageId, #groupId)
COMMIT
END
The row that causes the trouble and of which I'm unsure how to handle is this one:
SET #messageId = [dbo].[InsertNewMessage](#messageText, #dateTime, #bySMS, #byEmail)
The syntax seems ok because I can save it. When I run it I get the error message:
Running [dbo].[InsertMessageFromUserToGroup] ( #userEmail = test#test.com, #groupId = 5, #messageText = sdfsdf, #bySMS = false, #byEmail = true ).
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.InsertNewMessage", or the name is ambiguous.
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
No rows affected.
(0 row(s) returned)
#RETURN_VALUE =
Finished running [dbo].[InsertMessageFromUserToGroup].
It seems as if the other stored procedure can't be found. I've tried different ways of calling the procedure but everything else fails as well. Any suggestions?
Try changing
SET #messageId = [dbo].[InsertNewMessage](#messageText, #dateTime, #bySMS,
#byEmail)
to
EXEC #messageId = [dbo].[InsertNewMessage] #messageText, #dateTime, #bySMS,
#byEmail
Notice that SET has been changed to EXEC, and the parentheses have been removed from the parameters.
See the example in the MSDN documenation at the end of the article for more information.
I'm new at Crystal Reports and still learning so I'm wondering how I should do this. I have the following stored procedure:
CREATE PROCEDURE GetSurveyAnswerDetail
(#Question VARCHAR(255) = NULL, #AllowReportFlag CHAR(1) = NULL)
AS
SET NOCOUNT ON
DECLARE #rc INT
SET #rc = 1
IF (#Question IS NULL OR DATALENGTH(#Question) = 0
OR #AllowReportFlag IS NULL OR DATALENGTH(#AllowReportFlag) = 0)
RAISERROR('GetSurveyAnswerDetail is missing parameters.', 16, 1)
ELSE
BEGIN
DECLARE #AllowReport VARCHAR(100)
IF (#AllowReportFlag = 'N')
SET #AllowReport = ' AllowReport = ''Y'' AND '
ELSE
SET #AllowReport = ''
DECLARE #SQLStatement VARCHAR(5000)
SET #SQLStatement = 'SELECT COUNT(' + #Question + ') FROM tblSurveyAnswer WHERE ' + #AllowReport + #Question + ' != '''' GROUP BY ' + #Question + ' ORDER BY ' + #Question + ' DESC'
EXEC (#SQLStatement)
IF ##ERROR <> 0
RAISERROR('GetSurveyAnswerDetail has failed. Question may not exist.', 16, 1)
ELSE
SET #rc = 0
END
RETURN #rc
GO
This returns a list of numbers. What I'd like to do is create a pie chart from these numbers in Crystal Reports. I know you can set your data source from a stored procedure but when I do this, there are no fields I can choose. I'm probably going about this the wrong way so I'd appreciate any comments.
Michael, try making your stored procedure return a table. My guess is that you don't see any fields because you aren't returning any. Change the return line to
SELECT #rc AS Result
This should show you the Result as a field in the Report. I'm not sure that you can run the proc individually on a loop to manufacture a pie-chart. You may need to return all the data you want out of one stored procedure.
There must be a select query that is not hiding behind an if statement.
If you stored procedure is:
If #question = 'Y'
begin
SET #SQLStatement = 'select field from table where condition='OK'
EXEC (#SQLStatement)
end
In this example no fields will be shown. Change it to:
If #question = 'Y'
begin
SET #SQLStatement = 'select field from table where condition='OK'
end
else
Begin
select field from table where condition='impossiblecondition'
end
In this example it will work and fields will be shown.
I create a dummy parameter like #question and pass the 'Y'.