Use IF / ELSE IF on STORED PROCEDURE in Sql Server 2005 - stored-procedures

I have problem with this STORED PROCEDURE in Sql Server.
Any value entered as a parameter extracts data with parameter 'S'.
Can you please help me figure out the problem?
Thanks in advance.
My code below.
ALTER PROCEDURE [dbo].[xxxx](#StartDate VARCHAR(10),#EndDate VARCHAR(10),#Parameter CHAR(1))
AS
IF #Parameter='S'
BEGIN
SELECT * FROM doTable_S
END
ELSE IF #Parameter='A'
BEGIN
SELECT * FROM doTable_A
END
#EDIT01
ALTER PROCEDURE [dbo].[xxxx](#StartDate VARCHAR(10),#EndDate VARCHAR(10),#Parameter CHAR(1))
AS
BEGIN
IF #Parameter='S'
BEGIN
SELECT * FROM doTable_S
END
ELSE IF #Parameter='A'
BEGIN
SELECT * FROM doTable_A
END
END

Related

ruby - make a script continue to next statement in begin after the exception and done with rescue

Consider my code as
begin
aa = 20
bb = 0
puts 'before exception'
c = aa / bb
puts 'after exception'
rescue
puts 'in rescue'
end
It gives the output as
before exception
in rescue
If i want to print the 'after exception' as well. How i need to do that?
I need to continue with the next statement after the exception raise. Kindly help me on this.
Edit: I just mentioned a sample code above. Consider, i may not aware where and what exception will occur and it may come any where in the script and after done with executing rescue i need to go back to the next line in begin and work on it. Is there any way to handle this in ruby?
You cannot inside the begin block. Although if any code needs to run even after exception, use ensure block for it.
begin
aa = 20
bb = 0
puts 'before exception'
c = aa / bb
rescue
puts 'in rescue'
ensure
puts 'after exception'
end
Below is way to solve one such case on custom exception, or you will need to divide the code block into pieces and have a begin end block for what you feel it could look like raise a exception.
class Exception
attr_accessor :continuation
def ignore
continuation.call
end
end
require 'continuation' # Ruby 1.9
module RaiseWithIgnore
def raise(*args)
callcc do |continuation|
begin
super
rescue Exception => e
e.continuation = continuation
super(e)
end
end
end
end
class Object
include RaiseWithIgnore
end
def mj
puts 'before exception'
raise 'll'
puts 'after exception'
end
begin
mj
rescue => e
puts 'in rescue'
e.ignore
end
Hope this helps.
source : http://avdi.org/talks/rockymtnruby-2011/things-you-didnt-know-about-exceptions.html
This is a really good question. Ruby really should have provided a way to ignore the exception and continue to the next line in the rescue block.
It seems the only option is to use inline rescue, which is being frowned upon as not a good style.
begin
aa = 20
bb = 0
puts 'before exception'
c = aa / bb rescue nil
puts 'after exception'
end

Batching when using ActiveRecord::Base.connection.execute

I am busy writing an migration that will allow us to move our yamler from Syck to Psych and finally upgrade our project to ruby 2. This migration is going to be seriously resource intensive though so I am going to need to use chunking.
I wrote the following method to confirm that the result of the migration I plan to use produces the expected result and can be done without down time. To avoid Active record performing the serialization automatically I needed to use ActiveRecord::Base.connection.execute
My method that describes the transformation is as follows
def show_summary(table, column_name)
a = ActiveRecord::Base.connection.execute <<-SQL
SELECT id, #{column_name} FROM #{table}
SQL
all_rows = a.to_a; ""
problem_rows = all_rows.select do |row|
original_string = Syck.dump(Syck.load(row[1]))
orginal_object = Syck.load(original_string)
new_string = Psych.dump(orginal_object)
new_object = Syck.load(new_string)
Syck.dump(new_object) != original_string rescue true
end
problem_rows.map do |row|
old_string = Syck.dump(Syck.load(row[1]))
new_string = Psych.dump(Syck.load(old_string)) rescue "Parse failure"
roundtrip_string = begin
Syck.dump(Syck.load(new_string))
rescue => e
e.message
end
new_row = {}
new_row[:id] = row[0]
new_row[:original_encoding] = old_string
new_row[:new_encoding] = roundtrip_string
new_row
end
end
How can you use batching when making use of ActiveRecord::Base.connection.execute ?
For completeness my update function is as follows
# Migrate the given serialized YAML column from Syck to Psych
# (if any).
def migrate_to_psych(table, column)
table_name = ActiveRecord::Base.connection.quote_table_name(table)
column_name = ActiveRecord::Base.connection.quote_column_name(column)
fetch_data(table_name, column_name).each do |row|
transformed = ::Psych.dump(convert(Syck.load(row[column])))
ActiveRecord::Base.connection.execute <<-SQL
UPDATE #{table_name}
SET #{column_name} = #{ActiveRecord::Base.connection.quote(transformed)}
WHERE id = #{row['id']};
SQL
end
end
def fetch_data(table_name, column_name)
ActiveRecord::Base.connection.select_all <<-SQL
SELECT id, #{column_name}
FROM #{table_name}
WHERE #{column_name} LIKE '---%'
SQL
end
Which I got from http://fossies.org/linux/openproject/db/migrate/migration_utils/legacy_yamler.rb
You can easily build something with SQL's LIMIT and OFFSET clauses:
def fetch_data(table_name, column_name)
batch_size, offset = 1000, 0
begin
batch = ActiveRecord::Base.connection.select_all <<-SQL
SELECT id, #{column_name}
FROM #{table_name}
WHERE #{column_name} LIKE '---%'
LIMIT #{batch_size}
OFFSET #{offset}
SQL
batch.each do |row|
yield row
end
offset += batch_size
end until batch.empty?
end
which you can use almost exactly the same as before, just without the .each:
fetch_data(table_name, column_name) do |row| ... end
HTH!

Ruby on Rails How to treat a error from a method call

I have this ruby code:
def get_last_quote(ticker)
todays_date = Date.today
data = YahooFinance::Scraper::Company.new(ticker.downcase).historical_prices(todays_date, todays_date)
return data.first[:close]
end
When today's date is Sunday or Saturday I don't want any data, because markets are closed. Same thing happens on holidays or for any other day when the markets are closed.
So if it fails I want to subtract 1 from the days and check again, until I find a valid day.
The problem is that when the day is not valid I get Ruby on Rails error and I don't know how to treat it.
I tried:
while data.nil?
But it does not work, the error happens when I try to attribute the result to data, so I don't have a chance to check whether data is valid or not.
Any ideas, is it possible?
use begin then rescue ErrorClass with finally end
example
def method(args)
args += 1
end
def call_method
begin
method(92929292)
rescue ArgumentError, e
e.message
end
end

How do you access database error information when using Rails and Postgres

I am using find_by_sql to connect to a Postgres database and execute a database function. The database function executes a number of SQL statements and raises exceptions as required.
How do I trap the error code and error message raised by the Postgres function in Rails?
def self.validate_email(systemuserid, emailaddress)
begin
result = (self.find_by_sql(["SELECT fn_systemuser_validate_email(?, ?) AS returncode",
systemuserid, emailaddress])).first
rescue => err
# I want to get access to the error code and error message here and act accordingly
# errno = ??
# errmsg = ??
if errno == 10000
end
end
return result[:returncode]
end
I started by trying to find this information in the connection object - no such luck.
Any help much appreciated.
Currently active record replaces the original error with an internal one without passing on the original with the new error. I cant understand why any one would want this.
So the only solution right now is to monkey patch ;)
module ActiveRecord
module ConnectionAdapters
class AbstractAdapter
def translate_exception(e, message)
ActiveRecord::WrappedDatabaseException.new(message,e)
end
# Replaces
# def translate_exception(e, message)
# # override in derived class
# ActiveRecord::StatementInvalid.new(message)
# end
end
end
end
Now you can get the original_exception.
def self.validate_email(systemuserid, emailaddress)
begin
result = (self.find_by_sql(["SELECT fn_systemuser_validate_email(?, ?) AS returncode", systemuserid, emailaddress])).first
rescue ActiveRecord::WrappedDatabaseException => e
pgerror = e.original_exception
# Exact api depends on PG version, check the docs for your version.
puts "Doing my stuff: #{pgerror.result.result_error_message}"
end
end
This works with pg version 0.11 and Rails 3.0.9. Will probably work with later versions.
I let this one go for a while, (9 months!) but picked it up again due to a new impetus.
I used the monkey patch suggested by Darwin (sorry that the pull request didnt get the vote) and have then discovered that the code I need (with reference to http://deveiate.org/code/pg/PG/Result.html) is as follows:
rescue ActiveRecord::WrappedDatabaseException => e
pgerror = e.original_exception
sqlstate = pgerror.result.error_field(PG::Result::PG_DIAG_SQLSTATE )
end
Just look at .cause.
begin
# whatever.
rescue => err
p err.cause
end
You can user the errors array of your model, like others database:
errmsg = YourModel.errors[0].full_messages

How to use PostgreSQL triggers?

I am trying to use PostgreSQL triggers in my rails app. So I tried using this migration where execution of triggers is supposedly easy:
-- class AddTriggersToProducts < ActiveRecord::Migration
def self.up
table :products
execute %q{
create trigger trig1 before insert on products for each row
begin
price = price + 5
end;
}
end
def self.down
execute 'DROP TRIGGER trig1'
end
end
But this didn't change anything. I don't know where to write the procedure or function if I am going to use one here ...
"Creating a trigger" consists of two steps in PostgreSQL:
1.) Create a trigger function - with special return value trigger:
CREATE FUNCTION trg_update_prod_price()
RETURNS trigger AS
$func$
BEGIN
NEW.price := NEW.price + 5;
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
Multiple triggers can use the same trigger function.
2.) Create a trigger calling an existing trigger function:
CREATE TRIGGER update_prod_price
BEFORE INSERT ON products
FOR EACH ROW EXECUTE PROCEDURE trg_update_prod_price();
To "drop the trigger" (meaning the trigger function), you have to first drop all triggers referencing it and then drop the trigger function itself.
DROP TRIGGER update_prod_price ON products;
DROP FUNCTION trg_update_prod_price();
If you drop a table, all attached triggers are dropped with it. No need to drop those separately.
Does something like this work? Creating a function and then executing the function for the trigger:
def self.up
execute %q{
create or replace function update_price() returns trigger as $$
begin
NEW.price := NEW.price + 5;
return NEW;
end;
$$ language plpgsql }
execute %{ create trigger trig1 before insert on products for each row execute function update_price()}
end
The hair_trigger gem is a nice way to manage the creation of triggers.
Here is an example from hair_trigger's docs:
class AccountUser < ActiveRecord::Base
trigger.after(:insert) do
"UPDATE accounts SET user_count = user_count + 1 WHERE id = NEW.account_id;"
end
trigger.after(:update).of(:name) do
"INSERT INTO user_changes(id, name) VALUES(NEW.id, NEW.name);"
end
end

Resources