Sybase stored procs which use temp tables. Creation issue - stored-procedures

I am trying to create a sybase stored procedure which references a temp table, but I do not know the definition of this temp table. I could look at the proc and figure out what the temp table looks like and manually create it first, but I'm faced with approximately 1000 procs (which reference all sorts of temp tables) and this solution would be extremely tedious.
I've been looking for a more strategic approach but no luck so far. I'd appreciate it if you could share your thoughts with me.

It appears you may not understand that the whole point of a #table is that:
it is temporary
it exists only in the context of the stored proc that creates it
it is private
Therefore creating a new stored proc to "reference" the #table of another proc, is not a reasonable thing to attempt. Either write a completely independent stored proc with its own #table, or change the original stored proc so that the temporary table exists outside its context (see below).
You will have to jump through hoops, and different hoops for different versions of Sybase, to get at either the definition or the data in such #tables.
If you can catch the moment when one of those stored procs is executing, and you have sa privilege, you can certainly examine the DDL via SybaseCentral or other DBA tool.
If you are performing a documentation exercise, then there is no alternative to examining the sproc code; if you do not, you will miss important aspects of the #table that is buried in the code.
For temporary tables that are intended to be shared (ie. exist outside the context of a stored proc), instead of:
CREATE TABLE #my_table ...
use:
CREATE TABLE tempdb..my_table ...
and execute that outside any proc, before compiling the procs.

I think you could get #table metadata from tempdb systables and syscolumns tables.
Look at Rob Verschoor's article http://www.sypron.nl/temptab.html about #table name and tempdb dump load trick.

Related

Rails 4: How to delete join table entries via a migration?

I have a join table in rails that has a few entries that need to be deleted.
lets say the join table is named 'products_variants'
I found out i have a few entries in this join table that were created erroneously a while ago. I have their IDs, so i could go in phpmyadmin and delete them, but I want to make a migration to do it in case anyone uses an older database (which has happened before).
Since I don't have a ruby object representing this join table I cant do something like:
ProductsVariants.find(id_array)
How would i go about deleting these entries in a rails migration?
You can create AR class for this table inside of migration and use it for delete record.
How would you do it from the console? Whatever that is, put it in the migration. For example
class Cleanup < ActiveRecord::Migration
def up
execute("delete from product_variants where id in (1,2,3)")
end
def down
end
end
Barring a solution like maxd's answer, you can also delete them via plain 'ol SQL. If you already have the list of ids, you can do something like this:
ActiveRecord::Base.connection.execute("DELETE FROM products_variants WHERE id IN (...)")
Where ... is the list of ids to delete.
Semi-pointless side-note: Technically speaking, data manipulation is not typically done in the migrations for various reason; one of them being that you're usually not necessarily guaranteed that all (or even any) migrations will be run by your colleagues (speaking very generally here), or in the case of new local project setups (meaning, you've just pulled down the project code and are setting it up locally for the first time).
While it doesn't sound like this is an issue in your scenario, if you want to do this the Rails-y way, one alternative would be to put this in a Rake task, so that you or others can execute it as needed, rather than relying on the migrations.

Create Ruby on Rails project from an sql file

I have a previously separately managed sql file containing rather simple but large database. Would there be a way to import this sql file and generate ruby code as models using this data as a starting point for my future development?
Thank you for your help!
Yes!
It will take some work!
And you'll need to post a WHOLE HELL OF A LOT more detail to get more than that. ;-)
Taking a stab:
Rails can use legacy databases with a lot of effort manually specifying foreign key columns, table names, etc. It can be done. My suggestion, though, would be to convert the data in-place in whatever database you have by using a lot of ALTER TABLE RENAME... work and same for columns to make the old DB conform to Rails' convetions (primary key == 'id', table name is plural underscore'd version of model name, all that) before doing the import, and then you can just use plain vanilla ActiveRecord and all will be easy.

Duplicate Records created by find_or_create_by_

I have an ActiveRecord object, Corporation, and the only call in my project to create instances of this object looks like:
corp = Corporation.find_or_create_by_eveid_and_user_id(self.corporation_eveid, self.account.user_id)
Yet somehow, after my application has been running happily for a couple of days, there are duplicate records -- record where the eveid and user_id have the same values. How is this possible? Is there something I could be doing wrong in the way I update these records that would cause this problem?
I ended up added a unique, composite index to the table. That should solve the problem, but I don't understand how it's occurring.
This is Rails 3.0.7.
find_or_create does not perform any locking and makes no attempt to prevent race conditions. It's just a convenience method. If race conditions are a problem, you will need to either:
Use a transaction and roll back if you find somebody else has written just before you
(Better if you're actually expecting a race condition), perform pessimistic locking. This is where you SELECT from the table acquiring an exclusive lock first, then perform the write and clear the lock. In MySQL InnoDB tables, this is SELECT ... FOR UPDATE. If you have no reference point to lock on (i.e. no foreign key or anything that already exists in the database), then you'll have to stick with (1).
EDIT | If you can add a UNIQUE constraint at the schema level, I'd advise doing so too, if this is a genuine integrity concern.
Is this in your seeds file? Your best bet would be to write validations in your model to prevent the existence of a Corporation with the same eveid and user_id.
It seems to me that you seeded this information using find_or_create, which worked. But then maybe later in the day or another day someone created another one with the same information using your GUI. Validations would prevent this.
I have not tested this code, but something like this may work for you.
validates :eveid, :uniqueness => { :scope => :user_id }

Overwriting data to the model

I am using reading a table from Oracle and writing the data to a model using cronjob everymidnight so that it help me caching the data and enhance speed. BUT I am using create method to writing the data in model which create new entries and I get duplicate data in my model everytime. Is there any method in model to update the data or overwrite?
Model.each do |model|
p = Model.create model.attributes
p.save
end
Why do you want to save the models? It won't help caching. You should instead profile your application and implement caching techniques like memcached.
But anyways here's code to just read your table:
Model.each {|model| Model.new model.attributes }
Update according to your clarification: Copying from one DB to another without duplication could be done like so (given that Model1 accesses the source DB and Model2 access the destination DB):
Model1.each do |model1|
model2 = Model2.find_or_initialize_by_id model1.id, model1.attributes
model2.save!
}
This won't handle deletions, however. You may still want to look into memcached and maybe database sharding. It may also be worth thinking about a master/slave replication on database level where your "slow" database is the master (all database writes go to this) and the slave is the "fast" database (all read go to this). Web applications are usually read bound, so it will help in your case. Rails has support for this, see NewRelic's Scaling Rails Screencast Series about scaling your databases.
Use create_or_update instead of create.

Rails: Accessing a database not meant for Rails?

I have a standard rails application, that uses a mysql database through Active Record, with data loaded through a separate parsing process from a rather large XML file.
This was all well and good, but now I need to load data from an Oracle database, rather than the XML file.
I have no control how the database looks, and only really need a fraction of the data it contains (maybe one or two columns out of a few tables). As such, what I really want to do is make a call to the database, get data back, and put the data in the appropriate locations in my existing, Rails friendly mysql database.
How would I go about doing this? I've heard* you can (on a model by model basis) specifiy different databases for Rails Models to use, but that sounds like they use them in their entirety, (that is, the database is Rails friendly). Can I make direct Oracle calls? Is there a process that makes this easier? Can Active Record itself handle this?
A toy example:
If I need to know color, price, and location for an Object, then normally I would parse a huge XML file to get this information. Now, with oracle, color, price, and location are all in different tables, indexed by some ID (there isn't actually an "Object" table). I want to pull all this information together into my Rails model.
Edit: Sounds like what I'd heard about was ActiveRecord's "establish_connection" method...and it does indeed seem to assume one model is mapped to one table in the target database, which isn't true in my case.
Edit Edit: Ah, looks like I might be wrong there. "establish_connection" might handle my situation just fine (just gotta get ORACLE working in the first place, and I'll know for sure... If anyone can help, the question is here)
You can create a connection to Oracle directly and then have ActiveRecord execute a raw SQL statement to query your tables (plural). Off the top of my head, something like this:
class OracleModel < ActiveRecord::Base
establish_connection(:oracle_development)
def self.get_objects
self.find_by_sql("SELECT...")
end
end
With this model you can do OracleModel.get_objects which will return a set of records whereby the columns specified in the SELECT SQL statement are attributes of each OracleModel. Obviously you can probably come up with a more meaningful model name than I have!
Create an entry named :oracle_development in your config/database.yml file with your Oracle database connection details.
This may not be exactly what you are looking for, but it seems to cover you situation pretty well: http://pullmonkey.com/2008/4/21/ruby-on-rails-multiple-database-connections/
It looks like you can make an arbitrarily-named database configuration in the the database.yml file, and then have certain models connect to it like so:
class SomeModel < ActiveRecord::Base
establish_connection :arbitrary_database
#other stuff for your model
end
So, the solution would be to make ActiveRecord models for just the tables you want data out of from this other database. Then, if you really want to get into some sql, use ActiveRecord::Base.connection.execute(sql). If you need it as a the actual active_record object, do SomeModel.find_by_sql(sql).
Hope this helps!
I don't have points enough to edit your question, but it sounds like what you really need is to have another "connection pool" available to the second DB -- I don't think Oracle itself will be a problem.
Then, you need to use these alternate connections to "simply" execute a custom query within the appropriate controller method.
If you only need to pull data from your Oracle database, and if you have any ability to add objects to a schema that can see the data you require . . . .
I would simplify things by creating a view on the Oracle table that projects the data you require in a nice friendly shape for ActiveRecord.
This would mean maintaining code to two layers of the application, but I think the gain in clarity on the client-side would outweigh the cost.
You could also use the CREATE OR REPLACE VIEW Object AS SELECT tab1., tab2. FROM tab1,tab2 syntax so the view returned every column in each table.
If you need to Insert or Update changes to your Rails model, then you need to read up on the restrictions for doing Updates through a view.
(Also, you may need to search on getting Oracle to work with Rails as you will potentially need to install the Oracle client software and additional Ruby modules).
Are you talking about an one-time data conversion or some permanent data exchange between your application and the Oracle database? I think you shouldn't involve Rails in. You could just make a SQL query to the Oracle database, extract the data, and then just insert it into the MySQL database.

Resources